From 52930cf8f6e92d4b54d0b6b3f2c13bf45eb44059 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 12 Jun 2024 15:27:59 +0200 Subject: [PATCH 1/9] Build arm64 Windows executable --- .github/workflows/workflow.yaml | 15 +++++----- src/harness/os/windows.c | 50 +++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 357f6969..6cd2754f 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -15,11 +15,12 @@ jobs: strategy: matrix: platform: - - { name: 'Linux', arch: 'x64', os: ubuntu-latest, werror: true } - - { name: 'Linux', arch: 'arm64', os: ubuntu-latest, werror: true, cmake-toolchain-file: 'cmake/toolchains/linux-aarch64.cmake', apt-packages: 'gcc-aarch64-linux-gnu g++-aarch64-linux-gnu', cross: true } - - { name: 'MacOS', arch: 'arm64-x64', os: macos-latest, werror: true, cmake-args: '-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"' } - - { name: 'Windows', arch: 'Win32', os: windows-latest } - - { name: 'Windows', arch: 'x64', os: windows-latest } + - { name: 'Linux', arch: 'x64', os: ubuntu-latest, werror: true } + - { name: 'Linux', arch: 'arm64', os: ubuntu-latest, werror: true, cmake-toolchain-file: 'cmake/toolchains/linux-aarch64.cmake', apt-packages: 'gcc-aarch64-linux-gnu g++-aarch64-linux-gnu', cross: true } + - { name: 'MacOS', arch: 'arm64-x64', os: macos-latest, werror: true, cmake-args: '-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"' } + - { name: 'Windows', arch: 'x86', os: windows-latest, msvc-arch: 'Win32' } + - { name: 'Windows', arch: 'x64', os: windows-latest, msvc-arch: 'x64' } +# - { name: 'Windows', arch: 'arm64', os: windows-latest, msvc-arch: 'amd64_arm64', cross: true } defaults: run: @@ -33,9 +34,9 @@ jobs: - name: Set up Ninja uses: aseprite/get-ninja@main - uses: ilammy/msvc-dev-cmd@v1.13.0 - if: runner.os == 'Windows' + if: ${{ !!matrix.platform.msvc-arch }} with: - arch: ${{ matrix.platform.arch }} + arch: ${{ matrix.platform.msvc-arch }} - name: Install Linux dependencies if: ${{ runner.os == 'Linux' }} run: | diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index ddffafe0..93d69011 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -6,6 +6,7 @@ #include #include "harness/os.h" +#include "harness/trace.h" #include #include @@ -18,7 +19,7 @@ #include #include -#ifdef _WIN64 +#if defined(_WIN64) || defined(_M_ARM64) #define Esp Rsp #define Eip Rip #define Ebp Rbp @@ -32,6 +33,21 @@ static char windows_program_name[1024]; static char dirname_buf[_MAX_DIR]; static char fname_buf[_MAX_FNAME]; +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86) +#define DETHRACE_CPU_X86 1 +#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define DETHRACE_CPU_X64 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define DETHRACE_CPU_ARM64 1 +#endif + +#if defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) || defined(DETHRACE_CPU_ARM64) +#define DETHRACE_STACKWALK 1 +#else +#pragma message("Unsupported architecture: don't know how to StackWalk") +#endif + +#ifdef DETHRACE_STACKWALK static int addr2line(char const* const program_name, void const* const addr) { char addr2line_cmd[512] = { 0 }; @@ -48,14 +64,26 @@ static void print_stacktrace(CONTEXT* context) { STACKFRAME frame = { 0 }; /* setup initial stack frame */ - frame.AddrPC.Offset = context->Eip; frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = context->Esp; frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context->Ebp; frame.AddrFrame.Mode = AddrModeFlat; +#if defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) +#if defined(DETHRACE_CPU_X86) + DWORD machine_type = IMAGE_FILE_MACHINE_I386; +#else + DWORD machine_type = IMAGE_FILE_MACHINE_AMD64; +#endif + frame.AddrFrame.Offset = context->Ebp; + frame.AddrStack.Offset = context->Esp; + frame.AddrPC.Offset = context->Eip; +#elif defined(DETHRACE_CPU_ARM64) + DWORD machine_type = IMAGE_FILE_MACHINE_ARM64; + frame.AddrFrame.Offset = context->Fp; + frame.AddrStack.Offset = context->Sp; + frame.AddrPC.Offset = context->Pc; +#endif - while (StackWalk(IMAGE_FILE_MACHINE_I386, + while (StackWalk(machine_type, GetCurrentProcess(), GetCurrentThread(), &frame, @@ -142,15 +170,25 @@ static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { print_stacktrace(ExceptionInfo->ContextRecord); } else { - addr2line(windows_program_name, (void*)ExceptionInfo->ContextRecord->Eip); +#if defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) + void *addr = (void*)ExceptionInfo->ContextRecord->Eip; +#elif defined(DETHRACE_CPU_ARM64) + void *addr = (void*)ExceptionInfo->ContextRecord->Pc; +#endif + addr2line(windows_program_name, addr); } return EXCEPTION_EXECUTE_HANDLER; } +#endif void OS_InstallSignalHandler(char* program_name) { +#ifdef DETHRACE_STACKWALK strcpy(windows_program_name, program_name); SetUnhandledExceptionFilter(windows_exception_handler); +#else + LOG_WARN("Unsupported architecture. No signal handlers installed"); +#endif } FILE* OS_fopen(const char* pathname, const char* mode) { From 0ad96de2a5cb4e1aea7cf4b54434469c1cef7a74 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 15:44:05 +0200 Subject: [PATCH 2/9] Use dbghelp to print a stacktrace and use addr2line as last resort --- src/harness/os/windows.c | 219 +++++++++++++++++++++++++++++++-------- 1 file changed, 176 insertions(+), 43 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index b9f389ba..76d52e9f 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -2,8 +2,7 @@ // this has to be first #include - -#include +#include #include "harness/config.h" #include "harness/os.h" @@ -20,16 +19,11 @@ #include #include -#if defined(_WIN64) || defined(_M_ARM64) -#define Esp Rsp -#define Eip Rip -#define Ebp Rbp -#endif - void dr_dprintf(char* fmt_string, ...); static int stack_nbr = 0; static char windows_program_name[1024]; +static char path_addr2line[1024]; static char dirname_buf[_MAX_DIR]; static char fname_buf[_MAX_FNAME]; @@ -40,27 +34,146 @@ static char fname_buf[_MAX_FNAME]; #define DETHRACE_CPU_X64 1 #elif defined(__aarch64__) || defined(_M_ARM64) #define DETHRACE_CPU_ARM64 1 +#elif defined(__arm__) || defined(_M_ARM) +#define DETHRACE_CPU_ARM32 1 #endif -#if defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) || defined(DETHRACE_CPU_ARM64) -#define DETHRACE_STACKWALK 1 -#else +#if !(defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) || defined(DETHRACE_CPU_ARM32) || defined(DETHRACE_CPU_ARM64)) #pragma message("Unsupported architecture: don't know how to StackWalk") #endif -#ifdef DETHRACE_STACKWALK -static int addr2line(char const* const program_name, void const* const addr) { - char addr2line_cmd[512] = { 0 }; +static BOOL print_addr2line_address_location(HANDLE const hProcess, const DWORD64 address) { + char addr2line_cmd[1024] = { 0 }; + const char *program_name = windows_program_name; + IMAGEHLP_MODULE64 module_info; + + if (path_addr2line[0] == '\0') { + return FALSE; + } + + memset(&module_info, 0, sizeof(module_info)); + module_info.SizeOfStruct = sizeof(module_info); + if (SymGetModuleInfo64(hProcess, address, &module_info)) { + program_name = module_info.ImageName; + } - sprintf(addr2line_cmd, "addr2line -f -p -e %.256s %p", program_name, addr); + sprintf(addr2line_cmd, "%.256s -f -p -e %.256s %lx", path_addr2line, program_name, (long int)address); fprintf(stderr, "%d: ", stack_nbr++); - return system(addr2line_cmd); + system(addr2line_cmd); + return TRUE; +} + +static void printf_windows_message(const char *format, ...) { + va_list ap; + char win_msg[512]; + FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + win_msg, sizeof(win_msg)/sizeof(*win_msg), + NULL); + size_t win_msg_len = strlen(win_msg); + while (win_msg[win_msg_len-1] == '\r' || win_msg[win_msg_len-1] == '\n' || win_msg[win_msg_len-1] == ' ') { + win_msg[win_msg_len-1] = '\0'; + win_msg_len--; + } + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, " (%s)\n", win_msg); +} + +static const char *get_simple_basename(const char *path) { + const char *pos = strrchr(path, '\\'); + if (pos) { + return pos + 1; + } + pos = strrchr(path, '/'); + if (pos) { + return pos + 1; + } + return path; +} + +static void init_dbghelp(HANDLE const hProcess) { + + SymInitialize(hProcess, 0, true); + + if (!SymRefreshModuleList(hProcess)) { + printf_windows_message("SymRefreshModuleList failed"); + } +} + +static void cleanup_dbghelp(HANDLE const hProcess) { + + SymCleanup(hProcess); +} + +static BOOL print_dbghelp_address_location(HANDLE const hProcess, const DWORD64 address) { + IMAGEHLP_MODULE64 module_info; + union { + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; + SYMBOL_INFO symbol_info; + } symbol; + DWORD64 dwDisplacement; + DWORD lineColumn = 0; + IMAGEHLP_LINE64 line; + const char *image_file_name; + const char *symbol_name; + const char *file_name; + char line_number[16]; + + memset(&module_info, 0, sizeof(module_info)); + module_info.SizeOfStruct = sizeof(module_info); + if (!SymGetModuleInfo64(hProcess, address, &module_info)) { + return FALSE; + } + image_file_name = get_simple_basename(module_info.ImageName); + + memset(&symbol, 0, sizeof(symbol)); + symbol.symbol_info.SizeOfStruct = sizeof(symbol.symbol_info); + symbol.symbol_info.MaxNameLen = MAX_SYM_NAME; + if (!SymFromAddr(hProcess, address, &dwDisplacement, &symbol.symbol_info)) { + return FALSE; + } + symbol_name = symbol.symbol_info.Name; + + line.SizeOfStruct = sizeof(line); + if (!SymGetLineFromAddr64(hProcess, address, &lineColumn, &line)) { + return FALSE; + } + file_name = line.FileName; + snprintf(line_number, sizeof(line_number), "Line %u", (unsigned int)line.LineNumber); + + fprintf(stderr, "%s!%s+0x%lx %s %s\n", image_file_name, symbol_name, (long unsigned int)dwDisplacement, file_name, line_number); + return TRUE; +} + +static void print_address_location(HANDLE hProcess, DWORD64 address) { + IMAGEHLP_MODULE64 module_info; + + if (print_dbghelp_address_location(hProcess, address)) { + return; + } + if (print_addr2line_address_location(hProcess, address)) { + return; + } + + memset(&module_info, 0, sizeof(module_info)); + module_info.SizeOfStruct = sizeof(module_info); + if (SymGetModuleInfo64(hProcess, address, &module_info)) { + fprintf(stderr, "%s 0x%lx\n", module_info.ImageName, (long unsigned int)address); + return; + } + fprintf(stderr, "0x%lx\n", (long unsigned int)address); } static void print_stacktrace(CONTEXT* context) { + HANDLE hProcess = GetCurrentProcess(); - SymInitialize(GetCurrentProcess(), 0, true); + init_dbghelp(hProcess); STACKFRAME frame = { 0 }; @@ -68,38 +181,53 @@ static void print_stacktrace(CONTEXT* context) { frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat; -#if defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) #if defined(DETHRACE_CPU_X86) DWORD machine_type = IMAGE_FILE_MACHINE_I386; -#else - DWORD machine_type = IMAGE_FILE_MACHINE_AMD64; -#endif frame.AddrFrame.Offset = context->Ebp; frame.AddrStack.Offset = context->Esp; frame.AddrPC.Offset = context->Eip; +#elif defined(DETHRACE_CPU_X64) + DWORD machine_type = IMAGE_FILE_MACHINE_AMD64; + frame.AddrFrame.Offset = context->Rbp; + frame.AddrStack.Offset = context->Rsp; + frame.AddrPC.Offset = context->Rip; +#elif defined(DETHRACE_CPU_ARM32) + DWORD machine_type = IMAGE_FILE_MACHINE_ARM; + frame.AddrFrame.Offset = context->Lr; + frame.AddrStack.Offset = context->Sp; + frame.AddrPC.Offset = context->Pc; #elif defined(DETHRACE_CPU_ARM64) DWORD machine_type = IMAGE_FILE_MACHINE_ARM64; frame.AddrFrame.Offset = context->Fp; frame.AddrStack.Offset = context->Sp; frame.AddrPC.Offset = context->Pc; +#else + fprintf(stderr, "Unsupported architecture: cannot produce a stacktrace\n"); #endif while (StackWalk(machine_type, - GetCurrentProcess(), - GetCurrentThread(), - &frame, - context, - 0, - SymFunctionTableAccess, - SymGetModuleBase, - 0)) { - addr2line(windows_program_name, (void*)frame.AddrPC.Offset); - } - - SymCleanup(GetCurrentProcess()); + GetCurrentProcess(), + GetCurrentThread(), + &frame, + context, + 0, + SymFunctionTableAccess, + SymGetModuleBase, + 0)) { + + if (frame.AddrPC.Offset == frame.AddrReturn.Offset) { + fprintf(stderr, "PC == Return Address => Possible endless callstack\n"); + break; + } + + print_address_location(hProcess, frame.AddrPC.Offset); + } + + cleanup_dbghelp(hProcess); } static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { + HANDLE hProcess; switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); @@ -166,30 +294,35 @@ static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) break; } fflush(stderr); + hProcess = GetCurrentProcess(); + init_dbghelp(hProcess); /* If this is a stack overflow then we can't walk the stack, so just show where the error happened */ if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { print_stacktrace(ExceptionInfo->ContextRecord); } else { -#if defined(DETHRACE_CPU_X86) || defined(DETHRACE_CPU_X64) - void *addr = (void*)ExceptionInfo->ContextRecord->Eip; -#elif defined(DETHRACE_CPU_ARM64) - void *addr = (void*)ExceptionInfo->ContextRecord->Pc; +#if defined(DETHRACE_CPU_X86) + DWORD64 addr = (DWORD64)ExceptionInfo->ContextRecord->Eip; +#elif defined(DETHRACE_CPU_X64) + DWORD64 addr = (DWORD64)ExceptionInfo->ContextRecord->Rip; +#elif defined(DETHRACE_CPU_ARM32) || defined(DETHRACE_CPU_ARM64) + DWORD64 addr = (DWORD64)ExceptionInfo->ContextRecord->Pc; #endif - addr2line(windows_program_name, addr); + print_address_location(hProcess, addr); } + cleanup_dbghelp(hProcess); return EXCEPTION_EXECUTE_HANDLER; } -#endif void OS_InstallSignalHandler(char* program_name) { -#ifdef DETHRACE_STACKWALK strcpy(windows_program_name, program_name); + const char *env_addr2line = getenv("ADDR2LINE"); + strcpy(path_addr2line, env_addr2line ? env_addr2line : "addr2line.exe"); + if (_access(path_addr2line, R_OK | X_OK) != (R_OK | X_OK)) { + path_addr2line[0] = '\0'; + } SetUnhandledExceptionFilter(windows_exception_handler); -#else - LOG_WARN("Unsupported architecture. No signal handlers installed"); -#endif } FILE* OS_fopen(const char* pathname, const char* mode) { From 8f7cbdf17ffa6e8fca4077aab66b77306e247965 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 15:47:38 +0200 Subject: [PATCH 3/9] Print stack depth --- src/harness/os/windows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 76d52e9f..b0795d56 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -59,7 +59,6 @@ static BOOL print_addr2line_address_location(HANDLE const hProcess, const DWORD6 sprintf(addr2line_cmd, "%.256s -f -p -e %.256s %lx", path_addr2line, program_name, (long int)address); - fprintf(stderr, "%d: ", stack_nbr++); system(addr2line_cmd); return TRUE; } @@ -154,6 +153,7 @@ static BOOL print_dbghelp_address_location(HANDLE const hProcess, const DWORD64 static void print_address_location(HANDLE hProcess, DWORD64 address) { IMAGEHLP_MODULE64 module_info; + fprintf(stderr, "%d: ", stack_nbr++); if (print_dbghelp_address_location(hProcess, address)) { return; } From bbcf68fd8635359a1e54bd718143eca088ffbd57 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 16:26:58 +0200 Subject: [PATCH 4/9] Cleanup windows.c includes + use OS_Basename + define [RX]_OK ourselves --- src/harness/os/windows.c | 43 ++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index b0795d56..6c70da38 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -8,16 +8,19 @@ #include "harness/os.h" #include "harness/trace.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include /* _access */ +#include +#include /* errno_t, FILE, fopen_s, fprintf*/ +#include /* _splitpath */ +#include /* strcpy, strerror, strlen, strrchr */ + +#ifndef R_OK +#define R_OK 0 +#endif + +#ifndef X_OK +#define X_OK 1 +#endif void dr_dprintf(char* fmt_string, ...); @@ -84,21 +87,11 @@ static void printf_windows_message(const char *format, ...) { fprintf(stderr, " (%s)\n", win_msg); } -static const char *get_simple_basename(const char *path) { - const char *pos = strrchr(path, '\\'); - if (pos) { - return pos + 1; - } - pos = strrchr(path, '/'); - if (pos) { - return pos + 1; - } - return path; -} - static void init_dbghelp(HANDLE const hProcess) { - SymInitialize(hProcess, 0, true); + if (!SymInitialize(hProcess, 0, TRUE)) { + printf_windows_message("SymInitialize failed"); + } if (!SymRefreshModuleList(hProcess)) { printf_windows_message("SymRefreshModuleList failed"); @@ -129,7 +122,7 @@ static BOOL print_dbghelp_address_location(HANDLE const hProcess, const DWORD64 if (!SymGetModuleInfo64(hProcess, address, &module_info)) { return FALSE; } - image_file_name = get_simple_basename(module_info.ImageName); + image_file_name = OS_Basename(module_info.ImageName); memset(&symbol, 0, sizeof(symbol)); symbol.symbol_info.SizeOfStruct = sizeof(symbol.symbol_info); @@ -222,8 +215,6 @@ static void print_stacktrace(CONTEXT* context) { print_address_location(hProcess, frame.AddrPC.Offset); } - - cleanup_dbghelp(hProcess); } static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { From 174a13af1072868206fe94094f7c1c88e868cb5c Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 16:54:39 +0200 Subject: [PATCH 5/9] Cannot do _access(X_OK) on Windows --- src/harness/os/windows.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 6c70da38..b3342d9c 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -18,10 +18,6 @@ #define R_OK 0 #endif -#ifndef X_OK -#define X_OK 1 -#endif - void dr_dprintf(char* fmt_string, ...); static int stack_nbr = 0; @@ -310,7 +306,7 @@ void OS_InstallSignalHandler(char* program_name) { strcpy(windows_program_name, program_name); const char *env_addr2line = getenv("ADDR2LINE"); strcpy(path_addr2line, env_addr2line ? env_addr2line : "addr2line.exe"); - if (_access(path_addr2line, R_OK | X_OK) != (R_OK | X_OK)) { + if (_access(path_addr2line, R_OK) != (R_OK)) { path_addr2line[0] = '\0'; } SetUnhandledExceptionFilter(windows_exception_handler); From a3eb9270146c1ba10379a97477ba0c0ebac06a36 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 17:04:07 +0200 Subject: [PATCH 6/9] SymInitialize: don't invade process --- src/harness/os/windows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index b3342d9c..2d649043 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -85,7 +85,7 @@ static void printf_windows_message(const char *format, ...) { static void init_dbghelp(HANDLE const hProcess) { - if (!SymInitialize(hProcess, 0, TRUE)) { + if (!SymInitialize(hProcess, NULL, FALSE)) { printf_windows_message("SymInitialize failed"); } From e81082ec63a47d834d08184bd033d6dc5cb737b7 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 19:25:21 +0200 Subject: [PATCH 7/9] Use _access_s --- src/harness/os/windows.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 2d649043..7a251130 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -8,14 +8,15 @@ #include "harness/os.h" #include "harness/trace.h" -#include /* _access */ +#include /* errno, strerror */ +#include /* _access_s, F_OK */ #include -#include /* errno_t, FILE, fopen_s, fprintf*/ +#include /* errno_t, FILE, fgets, fopen_s, fprintf*/ #include /* _splitpath */ #include /* strcpy, strerror, strlen, strrchr */ -#ifndef R_OK -#define R_OK 0 +#ifndef F_OK +#define F_OK 0 #endif void dr_dprintf(char* fmt_string, ...); @@ -56,7 +57,7 @@ static BOOL print_addr2line_address_location(HANDLE const hProcess, const DWORD6 program_name = module_info.ImageName; } - sprintf(addr2line_cmd, "%.256s -f -p -e %.256s %lx", path_addr2line, program_name, (long int)address); + sprintf(addr2line_cmd, "\"%.256s\" -f -p -e %.256s %lx", path_addr2line, program_name, (long int)address); system(addr2line_cmd); return TRUE; @@ -306,7 +307,9 @@ void OS_InstallSignalHandler(char* program_name) { strcpy(windows_program_name, program_name); const char *env_addr2line = getenv("ADDR2LINE"); strcpy(path_addr2line, env_addr2line ? env_addr2line : "addr2line.exe"); - if (_access(path_addr2line, R_OK) != (R_OK)) { + errno_t e = _access_s(path_addr2line, F_OK); + if (e != 0) { + fprintf(stderr, "ADDR2LINE does not exist (%s)\n", path_addr2line); path_addr2line[0] = '\0'; } SetUnhandledExceptionFilter(windows_exception_handler); From ddcc5ee0840788e27b65d799764576af74524886 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 19:34:11 +0200 Subject: [PATCH 8/9] Ignore failure to get symbol line and line number --- src/harness/os/windows.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 7a251130..5503345c 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -130,13 +130,15 @@ static BOOL print_dbghelp_address_location(HANDLE const hProcess, const DWORD64 symbol_name = symbol.symbol_info.Name; line.SizeOfStruct = sizeof(line); - if (!SymGetLineFromAddr64(hProcess, address, &lineColumn, &line)) { - return FALSE; + if (SymGetLineFromAddr64(hProcess, address, &lineColumn, &line)) { + file_name = line.FileName; + snprintf(line_number, sizeof(line_number), "Line %u", (unsigned int)line.LineNumber); + } else { + file_name = ""; + line_number[0] = '\0'; } - file_name = line.FileName; - snprintf(line_number, sizeof(line_number), "Line %u", (unsigned int)line.LineNumber); - fprintf(stderr, "%s!%s+0x%lx %s %s\n", image_file_name, symbol_name, (long unsigned int)dwDisplacement, file_name, line_number); + fprintf(stderr, "0x%lx %s!%s+0x%lx %s %s\n", (long unsigned int)address, image_file_name, symbol_name, (long unsigned int)dwDisplacement, file_name, line_number); return TRUE; } From ab51be030581c1df36eab0c72e131b32ab9d2ed9 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 5 Jul 2024 21:41:10 +0200 Subject: [PATCH 9/9] Only consider using addr2line when ADDR2LINE is set --- src/harness/os/windows.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 5503345c..2610691a 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -306,14 +306,19 @@ static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) } void OS_InstallSignalHandler(char* program_name) { - strcpy(windows_program_name, program_name); - const char *env_addr2line = getenv("ADDR2LINE"); - strcpy(path_addr2line, env_addr2line ? env_addr2line : "addr2line.exe"); - errno_t e = _access_s(path_addr2line, F_OK); - if (e != 0) { - fprintf(stderr, "ADDR2LINE does not exist (%s)\n", path_addr2line); - path_addr2line[0] = '\0'; + const char *env_addr2line; + + path_addr2line[0] = '\0'; + env_addr2line = getenv("ADDR2LINE"); + if (env_addr2line != NULL) { + errno_t e = _access_s(env_addr2line, F_OK); + if (e == 0) { + strcpy(path_addr2line, env_addr2line); + } else { + fprintf(stderr, "ADDR2LINE does not exist (%s)\n", path_addr2line); + } } + strcpy(windows_program_name, program_name); SetUnhandledExceptionFilter(windows_exception_handler); }