Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Windows arm64 build #371

Merged
merged 10 commits into from
Jul 9, 2024
15 changes: 8 additions & 7 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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: |
Expand Down
50 changes: 44 additions & 6 deletions src/harness/os/windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <imagehlp.h>

#include "harness/os.h"
#include "harness/trace.h"

#include <assert.h>
#include <direct.h>
Expand All @@ -18,7 +19,7 @@
#include <stdlib.h>
#include <string.h>

#ifdef _WIN64
#if defined(_WIN64) || defined(_M_ARM64)
#define Esp Rsp
#define Eip Rip
#define Ebp Rbp
Expand All @@ -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 };

Expand All @@ -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,
Expand Down Expand Up @@ -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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rely on having an addr2line executable on windows? We shouldn't use SymGetLineFromAddr64 or something instead?

Copy link
Collaborator Author

@madebr madebr Jul 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. That's an error (addr2line).
I'll fix it using functions from DbgHelp.

}

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) {
Expand Down