HaxeFoundation/hashlink

[hl/c] stack capture implementation for unix

kLabz opened this issue · 3 comments

Currently, hl/c stack captures are only implemented for Windows:

hashlink/src/hlc_main.c

Lines 58 to 95 in 8a63b99

static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
#ifdef HL_WIN_DESKTOP
static HANDLE stack_process_handle = NULL;
DWORD64 index;
IMAGEHLP_LINEW64 line;
struct {
SYMBOL_INFOW sym;
uchar buffer[256];
} data;
data.sym.SizeOfStruct = sizeof(data.sym);
data.sym.MaxNameLen = 255;
if( !stack_process_handle ) {
stack_process_handle = GetCurrentProcess();
SymSetOptions(SYMOPT_LOAD_LINES);
SymInitialize(stack_process_handle,NULL,(BOOL)1);
}
if( SymFromAddrW(stack_process_handle,(DWORD64)(int_val)addr,&index,&data.sym) ) {
DWORD offset = 0;
line.SizeOfStruct = sizeof(line);
line.FileName = USTR("\\?");
line.LineNumber = 0;
SymGetLineFromAddrW64(stack_process_handle, (DWORD64)(int_val)addr, &offset, &line);
*outSize = usprintf(out,*outSize,USTR("%s(%s:%d)"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber);
return out;
}
#endif
return NULL;
}
static int hlc_capture_stack( void **stack, int size ) {
int count = 0;
# ifdef HL_WIN_DESKTOP
count = CaptureStackBackTrace(2, size, stack, NULL) - 8; // 8 startup
if( count < 0 ) count = 0;
# endif
return count;
}

Haxe CI will now run hl/c tests on linux, and this will be needed there to give proper results (in the meantime, failing tests will be disabled for hl/c with a link to this issue). This would also be useful for linux users.

Any pointers on the lib / API required to do that ?

libunwind apparently

Also, quoting @Apprentice-Alchemist

Re HL call stacks: the JIT has a custom unwinder that relies on frame pointers and is mostly platform independent (but this does mean that it can't give very useful stack traces if there's a lot of foreign code involved, since it only knows about functions generated by the JIT)
https://github.com/HaxeFoundation/hashlink/blob/8a63b99eca0825c3a6dc0574e1404ded4c0eaad1/src/module.c#L41-L210HL/C on the other hand uses native apis, but that's only been implemented for Windows.
https://github.com/HaxeFoundation/hashlink/blob/8a63b99eca0825c3a6dc0574e1404ded4c0eaad1/src/hlc_main.c#L58-L94In the short term HL/C can be fixed by implementing the stack trace / symbol resolution stuff for Linux/macOS/etc. using libunwind.
In the long term it may be a good idea to get rid of the custom unwinder in the JIT and switch to libunwind/windows apis to enable more reliable and useful stacktraces when FFI is involved (both libunwind and windows have support for dynamically generated debug information).