Skip to content

Commit

Permalink
[compiler-rt] Add DumpAllRegisters impl (#99049)
Browse files Browse the repository at this point in the history
- Add implementation for x86_64 and linux
- Add test

The output is like

==XXYYZZ==Register values:
rax = 0x...  rbx = 0x...  rcx = 0x...  rdx = 0x...
rdi = 0x...  rsi = 0x...  rbp = 0x...  rsp = 0x...
 r8 = 0x...   r9 = 0x...  r10 = 0x...  r11 = 0x...
r12 = 0x...  r13 = 0x...  r14 = 0x...  r15 = 0x...
  • Loading branch information
chestnykh authored Jul 18, 2024
1 parent 0684db3 commit bda1893
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 1 deletion.
116 changes: 115 additions & 1 deletion compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2118,8 +2118,122 @@ bool SignalContext::IsTrueFaultingAddress() const {
return si->si_signo == SIGSEGV && si->si_code != 128;
}

UNUSED
static const char *RegNumToRegName(int reg) {
switch (reg) {
# if defined(__x86_64__)
case REG_RAX:
return "rax";
case REG_RBX:
return "rbx";
case REG_RCX:
return "rcx";
case REG_RDX:
return "rdx";
case REG_RDI:
return "rdi";
case REG_RSI:
return "rsi";
case REG_RBP:
return "rbp";
case REG_RSP:
return "rsp";
case REG_R8:
return "r8";
case REG_R9:
return "r9";
case REG_R10:
return "r10";
case REG_R11:
return "r11";
case REG_R12:
return "r12";
case REG_R13:
return "r13";
case REG_R14:
return "r14";
case REG_R15:
return "r15";
# elif defined(__i386__)
case REG_EAX:
return "eax";
case REG_EBX:
return "ebx";
case REG_ECX:
return "ecx";
case REG_EDX:
return "edx";
case REG_EDI:
return "edi";
case REG_ESI:
return "esi";
case REG_EBP:
return "ebp";
case REG_ESP:
return "esp";
# endif
default:
return NULL;
}
return NULL;
}

UNUSED
static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
const char *RegName = RegNumToRegName(RegNum);
# if defined(__x86_64__)
Printf("%s%s = 0x%016llx ", internal_strlen(RegName) == 2 ? " " : "",
RegName, ctx->uc_mcontext.gregs[RegNum]);
# elif defined(__i386__)
Printf("%s = 0x%08x ", RegName, ctx->uc_mcontext.gregs[RegNum]);
# endif
}

void SignalContext::DumpAllRegisters(void *context) {
// FIXME: Implement this.
# if SANITIZER_LINUX
ucontext_t *ucontext = (ucontext_t *)context;
# if defined(__x86_64__)
Report("Register values:\n");
DumpSingleReg(ucontext, REG_RAX);
DumpSingleReg(ucontext, REG_RBX);
DumpSingleReg(ucontext, REG_RCX);
DumpSingleReg(ucontext, REG_RDX);
Printf("\n");
DumpSingleReg(ucontext, REG_RDI);
DumpSingleReg(ucontext, REG_RSI);
DumpSingleReg(ucontext, REG_RBP);
DumpSingleReg(ucontext, REG_RSP);
Printf("\n");
DumpSingleReg(ucontext, REG_R8);
DumpSingleReg(ucontext, REG_R9);
DumpSingleReg(ucontext, REG_R10);
DumpSingleReg(ucontext, REG_R11);
Printf("\n");
DumpSingleReg(ucontext, REG_R12);
DumpSingleReg(ucontext, REG_R13);
DumpSingleReg(ucontext, REG_R14);
DumpSingleReg(ucontext, REG_R15);
Printf("\n");
# elif defined(__i386__)
// Duplication of this report print is caused by partial support
// of register values dumping. In case of unsupported yet architecture let's
// avoid printing 'Register values:' without actual values in the following
// output.
Report("Register values:\n");
DumpSingleReg(ucontext, REG_EAX);
DumpSingleReg(ucontext, REG_EBX);
DumpSingleReg(ucontext, REG_ECX);
DumpSingleReg(ucontext, REG_EDX);
Printf("\n");
DumpSingleReg(ucontext, REG_EDI);
DumpSingleReg(ucontext, REG_ESI);
DumpSingleReg(ucontext, REG_EBP);
DumpSingleReg(ucontext, REG_ESP);
Printf("\n");
# endif
(void)ucontext;
# endif
// FIXME: Implement this for other OSes and architectures.
}

static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Check that sanitizer prints registers dump_registers on dump_registers=1
// RUN: %clangxx %s -o %t
// RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
//
// REQUIRES: i386-target-arch

#include <signal.h>

int main() {
raise(SIGSEGV);
// CHECK-DUMP: Register values
// CHECK-DUMP-NEXT: eax = {{0x[0-9a-f]+}} ebx = {{0x[0-9a-f]+}} ecx = {{0x[0-9a-f]+}} edx = {{0x[0-9a-f]+}}
// CHECK-DUMP-NEXT: edi = {{0x[0-9a-f]+}} esi = {{0x[0-9a-f]+}} ebp = {{0x[0-9a-f]+}} esp = {{0x[0-9a-f]+}}
// CHECK-NODUMP-NOT: Register values
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Check that sanitizer prints registers dump_registers on dump_registers=1
// RUN: %clangxx %s -o %t
// RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
//
// REQUIRES: x86_64-target-arch

#include <signal.h>

int main() {
raise(SIGSEGV);
// CHECK-DUMP: Register values
// CHECK-DUMP-NEXT: rax = {{0x[0-9a-f]+}} rbx = {{0x[0-9a-f]+}} rcx = {{0x[0-9a-f]+}} rdx = {{0x[0-9a-f]+}}
// CHECK-DUMP-NEXT: rdi = {{0x[0-9a-f]+}} rsi = {{0x[0-9a-f]+}} rbp = {{0x[0-9a-f]+}} rsp = {{0x[0-9a-f]+}}
// CHECK-DUMP-NEXT: r8 = {{0x[0-9a-f]+}} r9 = {{0x[0-9a-f]+}} r10 = {{0x[0-9a-f]+}} r11 = {{0x[0-9a-f]+}}
// CHECK-DUMP-NEXT: r12 = {{0x[0-9a-f]+}} r13 = {{0x[0-9a-f]+}} r14 = {{0x[0-9a-f]+}} r15 = {{0x[0-9a-f]+}}
// CHECK-NODUMP-NOT: Register values
return 0;
}

0 comments on commit bda1893

Please sign in to comment.