#28 SetUnhandledExceptionFilter broken in mingw64?

open
nobody
None
5
2010-02-25
2010-02-25
Anonymous
No

Hey folks,

I'm porting a backtrace handler to win64, and I can't seem to get SetUnhandledExceptionFilter() to work when building with mingw64.

Here is a small sample to demonstrate. Essentially I would expect my_exception_handler() to be called due to the crash. This test works correctly on 32-bit windows via mingw (mingw-runtime 3.13), or on 64-bit windows via MSVC (2005/2008). But when I build/run this using mingw64 on a 64-bit machine it doesn't work.

$ cat test.cpp
#include <windows.h>
#include <stdio.h>

void crashit() {
printf("ok lets crashit\n");
fflush(stdout);
int *p = (int *)8;
*p = 4;
}

LONG CALLBACK my_exception_handler(LPEXCEPTION_POINTERS ecx) {
printf("my_exception_handler called!\n");
return EXCEPTION_EXECUTE_HANDLER;
}

int main(int argc, char *argv[]) {
// print some basic sizeof stuff
printf("in main\n");
printf("sizeof unsigned long %d\n", sizeof(unsigned long));
printf("sizeof unsigned long long %d\n", sizeof(unsigned long long));
int *x;
printf("sizeof pointer %d\n", sizeof(x));

// register my exception handler
SetUnhandledExceptionFilter(&my_exception_handler);
printf("just set exception filter\n");

// crash
crashit();
}

// here's the output building on win64 using mingw-64 (note my handler isn't called)
$ /path/to/mymingw64/bin/x86_64-w64-mingw32-g++.exe -static -g -o test -static-libgcc ; ./test.exe
in main
sizeof unsigned long 4
sizeof unsigned long long 8
sizeof pointer 8
just set exception filter
ok lets crashit

// this is building on 32-bit machine using older mingw
// building with MSVC on win64 has similar result (except sizeof changes of course)
$ /path/to/mingw-3.13/bin/g++.exe -g -static -o test test.cpp -static-libgcc ; ./test.exe
in main
sizeof unsigned long 4
sizeof unsigned long long 8
sizeof pointer 4
just set exception filter
ok lets crashit
my_exception_handler called!

Any ideas? I'm digging around the source in mingw-w64-crt/crt and I see that in crtexe.c it does SetUnhandledExceptionFilter(__gnu_exception_handler) and then calls __mingw_init_ehandler() on win64, which in turn uses RtlAddFunctionTable() to set __mingw_SEH_error_handler() as a toplevel handler in crt_handler.c. This is the handler that is ultimately called in my testcase. It sees the EXCEPTION_ACCESS_VIOLATION, and appears to check if there is a user defined handler to call but it doesn't find one.

So I'm wondering if a) SetUnhandledExceptionFilter() is broken in mingw64 and my handler is simply not being installed, or b) something replacing it later under the covers?

Thanks!

Discussion


Log in to post a comment.