From 291b24bcb1a99cfefecbaa6a84fe242dd8976a9a Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Tue, 17 May 2022 12:10:07 +0200 Subject: [PATCH 1/3] feat: Capture registers with inproc backend --- src/backends/sentry_backend_inproc.c | 75 +++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/backends/sentry_backend_inproc.c b/src/backends/sentry_backend_inproc.c index 2318e2774..fddd7147a 100644 --- a/src/backends/sentry_backend_inproc.c +++ b/src/backends/sentry_backend_inproc.c @@ -114,7 +114,8 @@ shutdown_inproc_backend(sentry_backend_t *UNUSED(backend)) reset_signal_handlers(); } -#elif defined SENTRY_PLATFORM_WINDOWS +#elif defined(SENTRY_PLATFORM_WINDOWS) + struct signal_slot { DWORD signum; const char *signame; @@ -168,8 +169,77 @@ shutdown_inproc_backend(sentry_backend_t *UNUSED(backend)) SetUnhandledExceptionFilter(current_handler); } } + #endif +sentry_value_t +sentry__registers_from_uctx(const sentry_ucontext_t *uctx) +{ + sentry_value_t registers = sentry_value_new_object(); + +#ifdef SENTRY_PLATFORM_UNIX + +#elif defined(SENTRY_PLATFORM_WINDOWS) + PCONTEXT ctx = uctx->exception_ptrs.ContextRecord; + +# define SET_REG(name, prop) \ + sentry_value_set_by_key(registers, name, \ + sentry__value_new_addr((uint64_t)(size_t)ctx->prop)); + +# if defined(_M_AMD64) + + if (ctx->ContextFlags & CONTEXT_INTEGER) { + SET_REG("rax", Rax); + SET_REG("rcx", Rcx); + SET_REG("rdx", Rdx); + SET_REG("rbx", Rbx); + SET_REG("rbp", Rbp); + SET_REG("rsi", Rsi); + SET_REG("rdi", Rdi); + SET_REG("r8", R8); + SET_REG("r9", R9); + SET_REG("r10", R10); + SET_REG("r11", R11); + SET_REG("r12", R12); + SET_REG("r13", R13); + SET_REG("r14", R14); + SET_REG("r15", R15); + } + + if (ctx->ContextFlags & CONTEXT_CONTROL) { + SET_REG("rsp", Rsp); + SET_REG("rip", Rip); + } + +# elif defined(_M_IX86) + + if (ctx->ContextFlags & CONTEXT_INTEGER) { + SET_REG("edi", Edi); + SET_REG("esi", Esi); + SET_REG("ebx", Ebx); + SET_REG("edx", Edx); + SET_REG("ecx", Ecx); + SET_REG("eax", Eax); + } + + if (ctx->ContextFlags & CONTEXT_CONTROL) { + SET_REG("ebp", Ebp); + SET_REG("eip", Eip); + SET_REG("eflags", EFlags); + SET_REG("esp", Esp); + } + +# else + // _ARM64_ +# endif + +# undef SET_REG + +#endif + + return registers; +} + static sentry_value_t make_signal_event( const struct signal_slot *sig_slot, const sentry_ucontext_t *uctx) @@ -217,6 +287,9 @@ make_signal_event( sentry_value_t stacktrace = sentry_value_new_stacktrace(&backtrace[0], frame_count); + sentry_value_t registers = sentry__registers_from_uctx(uctx); + sentry_value_set_by_key(stacktrace, "registers", registers); + sentry_value_set_by_key(exc, "stacktrace", stacktrace); sentry_event_add_exception(event, exc); From e16bab95cdc14e5f72201bde7884df462b747c60 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Tue, 17 May 2022 14:44:10 +0200 Subject: [PATCH 2/3] get the registers on linux platforms we care about --- src/backends/sentry_backend_inproc.c | 104 +++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/backends/sentry_backend_inproc.c b/src/backends/sentry_backend_inproc.c index fddd7147a..b2c92b6ca 100644 --- a/src/backends/sentry_backend_inproc.c +++ b/src/backends/sentry_backend_inproc.c @@ -179,6 +179,110 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) #ifdef SENTRY_PLATFORM_UNIX + // just assume the ctx is a bunch of uintpr_t, and index that directly + uintptr_t *ctx = (uintptr_t *)&uctx->user_context->uc_mcontext; + +# define SET_REG(name, num) \ + sentry_value_set_by_key(registers, name, \ + sentry__value_new_addr((uint64_t)(size_t)ctx[num])); + +# ifdef __linux__ +# ifdef __x86_64__ + + SET_REG("r8", 0); + SET_REG("r9", 1); + SET_REG("r10", 2); + SET_REG("r11", 3); + SET_REG("r12", 4); + SET_REG("r13", 5); + SET_REG("r14", 6); + SET_REG("r15", 7); + SET_REG("rdi", 8); + SET_REG("rsi", 9); + SET_REG("rbp", 10); + SET_REG("rbx", 11); + SET_REG("rdx", 12); + SET_REG("rax", 13); + SET_REG("rcx", 14); + SET_REG("rsp", 15); + SET_REG("rip", 16); + +# elif defined(__i386__) + + // gs, fs, es, ds + SET_REG("edi", 4); + SET_REG("esi", 5); + SET_REG("ebp", 6); + SET_REG("esp", 7); + SET_REG("ebx", 8); + SET_REG("edx", 9); + SET_REG("ecx", 10); + SET_REG("eax", 11); + SET_REG("eip", 14); + SET_REG("eflags", 16); + +# elif defined(__aarch64__) + + // 0 is `fault_address` + SET_REG("x0", 1); + SET_REG("x1", 2); + SET_REG("x2", 3); + SET_REG("x3", 4); + SET_REG("x4", 5); + SET_REG("x5", 6); + SET_REG("x6", 7); + SET_REG("x7", 8); + SET_REG("x8", 9); + SET_REG("x9", 10); + SET_REG("x10", 11); + SET_REG("x11", 12); + SET_REG("x12", 13); + SET_REG("x13", 14); + SET_REG("x14", 15); + SET_REG("x15", 16); + SET_REG("x16", 17); + SET_REG("x17", 18); + SET_REG("x18", 19); + SET_REG("x19", 20); + SET_REG("x20", 21); + SET_REG("x21", 22); + SET_REG("x22", 23); + SET_REG("x23", 24); + SET_REG("x24", 25); + SET_REG("x25", 26); + SET_REG("x26", 27); + SET_REG("x27", 28); + SET_REG("x28", 29); + SET_REG("fp", 30); + SET_REG("lr", 31); + SET_REG("sp", 32); + SET_REG("pc", 33); + +# elif defined(__arm__) + + // trap_no, _error_code, oldmask + SET_REG("r0", 3); + SET_REG("r1", 4); + SET_REG("r2", 5); + SET_REG("r3", 6); + SET_REG("r4", 7); + SET_REG("r5", 8); + SET_REG("r6", 9); + SET_REG("r7", 10); + SET_REG("r8", 11); + SET_REG("r9", 12); + SET_REG("r10", 13); + SET_REG("fp", 14); + SET_REG("ip", 15); + SET_REG("sp", 16); + SET_REG("lr", 17); + SET_REG("pc", 18); + +# endif +# endif + +# undef SET_REG + #elif defined(SENTRY_PLATFORM_WINDOWS) PCONTEXT ctx = uctx->exception_ptrs.ContextRecord; From d5ac9e7fae988feca4e521ffc9827a66281bd6e2 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Wed, 18 May 2022 11:37:37 +0200 Subject: [PATCH 3/3] finish cpu context for mac --- src/backends/sentry_backend_inproc.c | 106 +++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/src/backends/sentry_backend_inproc.c b/src/backends/sentry_backend_inproc.c index b2c92b6ca..7fc4dbe71 100644 --- a/src/backends/sentry_backend_inproc.c +++ b/src/backends/sentry_backend_inproc.c @@ -177,7 +177,7 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) { sentry_value_t registers = sentry_value_new_object(); -#ifdef SENTRY_PLATFORM_UNIX +#if defined(SENTRY_PLATFORM_LINUX) // just assume the ctx is a bunch of uintpr_t, and index that directly uintptr_t *ctx = (uintptr_t *)&uctx->user_context->uc_mcontext; @@ -186,8 +186,7 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) sentry_value_set_by_key(registers, name, \ sentry__value_new_addr((uint64_t)(size_t)ctx[num])); -# ifdef __linux__ -# ifdef __x86_64__ +# if defined(__x86_64__) SET_REG("r8", 0); SET_REG("r9", 1); @@ -207,7 +206,7 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) SET_REG("rsp", 15); SET_REG("rip", 16); -# elif defined(__i386__) +# elif defined(__i386__) // gs, fs, es, ds SET_REG("edi", 4); @@ -221,7 +220,7 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) SET_REG("eip", 14); SET_REG("eflags", 16); -# elif defined(__aarch64__) +# elif defined(__aarch64__) // 0 is `fault_address` SET_REG("x0", 1); @@ -258,7 +257,7 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) SET_REG("sp", 32); SET_REG("pc", 33); -# elif defined(__arm__) +# elif defined(__arm__) // trap_no, _error_code, oldmask SET_REG("r0", 3); @@ -278,7 +277,100 @@ sentry__registers_from_uctx(const sentry_ucontext_t *uctx) SET_REG("lr", 17); SET_REG("pc", 18); -# endif +# endif + +# undef SET_REG + +#elif defined(SENTRY_PLATFORM_DARWIN) + +# define SET_REG(name, prop) \ + sentry_value_set_by_key(registers, name, \ + sentry__value_new_addr((uint64_t)(size_t)thread_state->prop)); + +# if defined(__x86_64__) + + _STRUCT_X86_THREAD_STATE64 *thread_state + = &uctx->user_context->uc_mcontext->__ss; + + SET_REG("rax", __rax); + SET_REG("rbx", __rbx); + SET_REG("rcx", __rcx); + SET_REG("rdx", __rdx); + SET_REG("rdi", __rdi); + SET_REG("rsi", __rsi); + SET_REG("rbp", __rbp); + SET_REG("rsp", __rsp); + SET_REG("r8", __r8); + SET_REG("r9", __r9); + SET_REG("r10", __r10); + SET_REG("r11", __r11); + SET_REG("r12", __r12); + SET_REG("r13", __r13); + SET_REG("r14", __r14); + SET_REG("r15", __r15); + SET_REG("rip", __rip); + +# elif defined(__arm64__) + + _STRUCT_ARM_THREAD_STATE64 *thread_state + = &uctx->user_context->uc_mcontext->__ss; + + SET_REG("x0", __x[0]); + SET_REG("x1", __x[1]); + SET_REG("x2", __x[2]); + SET_REG("x3", __x[3]); + SET_REG("x4", __x[4]); + SET_REG("x5", __x[5]); + SET_REG("x6", __x[6]); + SET_REG("x7", __x[7]); + SET_REG("x8", __x[8]); + SET_REG("x9", __x[9]); + SET_REG("x10", __x[10]); + SET_REG("x11", __x[11]); + SET_REG("x12", __x[12]); + SET_REG("x13", __x[13]); + SET_REG("x14", __x[14]); + SET_REG("x15", __x[15]); + SET_REG("x16", __x[16]); + SET_REG("x17", __x[17]); + SET_REG("x18", __x[18]); + SET_REG("x19", __x[19]); + SET_REG("x20", __x[20]); + SET_REG("x21", __x[21]); + SET_REG("x22", __x[22]); + SET_REG("x23", __x[23]); + SET_REG("x24", __x[24]); + SET_REG("x25", __x[25]); + SET_REG("x26", __x[26]); + SET_REG("x27", __x[27]); + SET_REG("x28", __x[28]); + SET_REG("fp", __fp); + SET_REG("lr", __lr); + SET_REG("sp", __sp); + SET_REG("pc", __pc); + +# elif defined(__arm__) + + _STRUCT_ARM_THREAD_STATE *thread_state + = &uctx->user_context->uc_mcontext->__ss; + + SET_REG("r0", __r[0]); + SET_REG("r1", __r[1]); + SET_REG("r2", __r[2]); + SET_REG("r3", __r[3]); + SET_REG("r4", __r[4]); + SET_REG("r5", __r[5]); + SET_REG("r6", __r[6]); + SET_REG("r7", __r[7]); + SET_REG("r8", __r[8]); + SET_REG("r9", __r[9]); + SET_REG("r10", __r[10]); + SET_REG("fp", __r[11]); + SET_REG("ip", __r[12]); + SET_REG("sp", __sp); + SET_REG("lr", __lr); + SET_REG("pc", __pc); + # endif # undef SET_REG