views:

166

answers:

2

I'm trying to use the StackWalk64 function in DbgHelp.dll to get a stack trace when I receive a SIGSEGV, but the stack trace obtained is unrelated to the actual site of the access violation:

[0] sigsegv_handler() e:\hudson\jobs\ide-nightly-trunk\workspace\ide-nightly-trunk\core\ide\cspyserver\src\stackwalker\cssstackwalker.cpp:31
[1] XcptFilter() C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll
[2] __tmainCRTStartup() f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:603
[3] seh_longjmp_unwind4() C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll
[4] BaseThreadInitThunk() C:\Windows\syswow64\kernel32.dll
[5] RtlCreateUserProcess() C:\Windows\SysWOW64\ntdll.dll
[6] RtlCreateProcessParameters() C:\Windows\SysWOW64\ntdll.dll

I suspect that weird windows exception handling and setjmp/longjmp is involved, but I'm not really sure what I should be looking for.

A: 

I don't have any experience on Windows using the C-runtime support in this area. But I have had good success using the vectored exception handler feature (see MSDN AddVectoredExceptionHandler). The EXCEPTION_POINTERS structure passed to the handler can be used with the MiniDumpWriteDump API to produce a user mode dump file that you can open with WinDbg to inspect the exception.

Notes:
- you need to run .excr after opening the dump to switch to the exception context.
- Vector exception filters get called for all exceptions so be sure to filter out only those that you are interested in by looking at the EXCEPTION_RECORD::ExceptionCode passed to the filter.

Paul Arnold
+1  A: 

Please note that it's always going to be challenging to get a reliable stack fault after an access violation. By definition the process is corrupt when the AV occurs so it may be impossible to retrieve the actual stack trace afterwords (for instance what happens if the error which caused the exception also corrupted some of the structures used by your stack walking logic)?

In this case, it appears that you're trying to capture the stack trace in your exception filter which will never work - the exception filter is run on a partially unwound stack. You can find the exception record and the context record for the failure with the GetExceptionInformation API (this API only works from the filter expression so you need to do something like

  __try
  {
     <stuff>
  }
  __except(MyExceptionFilter(GetExceptionInformation())
  {
     <stuff>
  }

You should be able to retrieve the accurate stack trace with the context record and exception information.

Larry Osterman
Yes, I know that I don't have any guarantees that I can get a full stacktrace, but this about getting as much info out when the system has crashed, so a partial or broken stacktrace is better than nothing.
JesperE