Skip to content

Commit

Permalink
update backtrace handling
Browse files Browse the repository at this point in the history
  • Loading branch information
TheTechsTech committed Nov 14, 2024
1 parent f522f2e commit ef10538
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 23 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ endif()

project(
raii
VERSION 1.1.3
VERSION 1.1.4
DESCRIPTION "An general RAII implementation for C, with Defer, C11 Atomics/Threads with Thread Pool, and custom malloc/heap allocation."
HOMEPAGE_URL "https://zelang-dev.github.io/c-raii/"
LANGUAGES C
Expand Down
70 changes: 48 additions & 22 deletions src/except.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,11 @@ static void ex_print(ex_context_t *exception, const char *message) {
void ex_trace_set(ex_context_t *ex, void_t ctx) {
#if defined(USE_DEBUG)
#if defined(_WIN32)
// On x64, StackWalk64 modifies the context record, that could
// cause crashes, so we create a copy to prevent it
memcpy(ex->backtrace->ctx, (CONTEXT *)ctx, sizeof(CONTEXT));
if (ctx == NULL)
RtlCaptureContext((CONTEXT *)ex->backtrace->ctx);
else
memcpy(ex->backtrace->ctx, (CONTEXT *)ctx, sizeof(CONTEXT));

ex->backtrace->process = GetCurrentProcess();
ex->backtrace->thread = GetCurrentThread();
#else
Expand All @@ -160,7 +162,8 @@ void ex_trace_set(ex_context_t *ex, void_t ctx) {
void ex_backtrace(ex_backtrace_t *ex) { //Prints stack trace based on context record
#if defined(USE_DEBUG)
#if defined(_WIN32)
CONTEXT *ctxCopy = ex->ctx;
CONTEXT ctx, *c_ctx = (CONTEXT *)ex->ctx;
memcpy(&ctx, (CONTEXT *)ex->ctx, sizeof(CONTEXT));
HANDLE process = ex->process;
HANDLE thread = ex->thread;
DWORD64 TempAddress = (DWORD64)0;
Expand All @@ -180,13 +183,43 @@ void ex_backtrace(ex_backtrace_t *ex) { //Prints stack trace based on context re

memset(&stack, 0, sizeof(STACKFRAME64));
displacement = 0;
#if !defined(_M_AMD64)
stack.AddrPC.Offset = (*ctx).Eip;
DWORD imageType;
#ifdef _M_IX86
imageType = IMAGE_FILE_MACHINE_I386;
stack.AddrPC.Offset = (*c_ctx).Eip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*ctx).Esp;
stack.AddrFrame.Offset = (*c_ctx).Ebp;
stack.AddrFrame.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*c_ctx).Esp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrFrame.Offset = (*ctx).Ebp;
#elif defined(_M_X64) || defined(_M_AMD64)
imageType = IMAGE_FILE_MACHINE_AMD64;
stack.AddrPC.Offset = (*c_ctx).Rip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrFrame.Offset = (*c_ctx).Rsp;
stack.AddrFrame.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*c_ctx).Rsp;
stack.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
imageType = IMAGE_FILE_MACHINE_IA64;
stack.AddrPC.Offset = (*c_ctx).StIIP;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrFrame.Offset = (*c_ctx).IntSp;
stack.AddrFrame.Mode = AddrModeFlat;
stack.AddrBStore.Offset = (*c_ctx).RsBSP;
stack.AddrBStore.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*c_ctx).IntSp;
stack.AddrStack.Mode = AddrModeFlat;
#elif _M_ARM64
imageType = IMAGE_FILE_MACHINE_ARM64;
stack.AddrPC.Offset = (*c_ctx).Pc;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrFrame.Offset = (*c_ctx).Fp;
stack.AddrFrame.Mode = AddrModeFlat;
stack.AddrStack.Offset = (*c_ctx).Sp;
stack.AddrStack.Mode = AddrModeFlat;
#else
#error "Platform not supported!"
#endif

SymInitialize(process, NULL, TRUE); //load symbols
Expand All @@ -195,16 +228,11 @@ void ex_backtrace(ex_backtrace_t *ex) { //Prints stack trace based on context re
//get next call from stack
result = StackWalk64
(
#if defined(_M_AMD64)
IMAGE_FILE_MACHINE_AMD64
#else
IMAGE_FILE_MACHINE_I386
#endif
,
imageType,
process,
thread,
&stack,
ctxCopy,
&ctx,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
Expand All @@ -223,11 +251,11 @@ void ex_backtrace(ex_backtrace_t *ex) { //Prints stack trace based on context re

//try to get line
if (SymGetLineFromAddr64(process, stack.AddrPC.Offset, &disp, line)) {
fprintf(stderr, "\tat %s in %s: line: %lu: address: 0x%0zx\n", pSymbol->Name, line->FileName, line->LineNumber, pSymbol->Address);
fprintf(stderr, "\tat %s in %s:%lu: address: 0x%0zx\033[0K\n", pSymbol->Name, line->FileName, line->LineNumber, pSymbol->Address);
} else {
//failed to get line
if (pSymbol->Address != TempAddress)
fprintf(stderr, "\tat %s, address 0x%0zx.\n", pSymbol->Name, pSymbol->Address);
fprintf(stderr, "\tat %s, address 0x%0zx.\033[0K\n", pSymbol->Name, pSymbol->Address);

TempAddress = pSymbol->Address;
hModule = NULL;
Expand All @@ -239,7 +267,7 @@ void ex_backtrace(ex_backtrace_t *ex) { //Prints stack trace based on context re
if (hModule != NULL)GetModuleFileNameA(hModule, module, EX_MAX_NAME_LEN);

if (!is_str_empty(module))
fprintf(stderr, "in %s\n", module);
fprintf(stderr, "in %s\033[0K\n", module);
}

free(line);
Expand Down Expand Up @@ -302,7 +330,7 @@ ex_context_t *ex_init(void) {
context->is_emulated = false;
context->ex = NULL;
context->panic = NULL;
memset(context->backtrace, 0, sizeof(context->backtrace));
memset(context->backtrace->ctx, 0, sizeof(context->backtrace->ctx));
context->caught = -1;
context->type = ex_context_st;
ex_signal_unblock(all);
Expand Down Expand Up @@ -346,6 +374,7 @@ void ex_throw(const char *exception, const char *file, int line, const char *fun
ex_terminate();

ex_signal_block(all);
ex_trace_set(ctx, NULL);
ctx->ex = exception;
ctx->file = file;
ctx->line = line;
Expand All @@ -358,9 +387,6 @@ void ex_throw(const char *exception, const char *file, int line, const char *fun
else if (ctx->is_raii)
raii_unwind_set(ctx, ctx->ex, ctx->panic);

#ifndef _WIN32
ex_trace_set(ctx, NULL);
#endif
ex_unwind_stack(ctx);
ex_signal_unblock(all);

Expand Down

0 comments on commit ef10538

Please sign in to comment.