How to get a string description of a Win32 crash during top-level filtering (I'm looking for the instruction address at the top of the stack)

If I use a class / method like the one described here , how can I get the call description / address at the top of the stack?

Basically, I want some value that I can use when invoking our bug tracking system. I want to "uniquely" identify based on the address of the instruction that caused the exception.

(Usually this is something like the form mydll.dll! 1234ABDC ())

EDIT:

Some background information:

I am creating a minidump for emailing a defect tracking system (fogbugz). To reduce duplicates, I'm trying to come up with a reasonable โ€œsignatureโ€ for the crash. I know that there is an xml PI for FB, but this requires a login, and we are not sure yet that we can let people sniff our traffic and get information about users. Email is also easier to implement. Later we will use the XML API to send mini-disks.

+6
c ++ exception-handling winapi crash-dumps minidump
source share
4 answers

You need to put the code for this in your exception filter, by the time you get to the exception handler, most of the context information for the exception has been lost.

try { // whatever } except (MyExceptionFilter(GetExceptionInformation())) { } 

Your filter will look something like this.

 LONG WINAPI MyExceptionFilter ( EXCEPTION_POINTERS * pExcept, BOOL fPassOn) { EXCEPTION_RECORD * pER = pExcept->ExceptionRecord; DWORD dwExceptionCode = pER->ExceptionCode; TCHAR szOut[MAX_PATH*4]; // exception output goes here. szOut[0] = 0; MEMORY_BASIC_INFORMATION mbi; DWORD cb = VirtualQuery (pER->ExceptionAddress, &mbi, sizeof(mbi)); if (cb == sizeof(mbi)) { TCHAR szModule[MAX_PATH]; if (GetModuleFileName ((HMODULE)mbi.AllocationBase, szModule, MAX_PATH)) { wsprintf(szOut, "Exception at '%s' + 0x%X", szModule, (ULONG_PTR)pER->ExceptionAddress - (ULONG_PTR)mbi.AllocationBase); } } return EXCEPTION_EXECUTE_HANDLER; } 

Of course, you will need to adjust the bit a bit for 64-bit architectures, because in this case ExceptionAddress and AllocationBase will have 64-bit values.

+4
source share

The EXCEPTION_POINTERS structure, which is sent to TopLevelFilter() , contains the EXCEPTION_RECORD structure, which contains the ExceptionAddress . Which of these addresses can you find out in which DLL is the offensive opcode by listing the modules with CreateToolhelp32Snapshot . You can also use the functions in dbghelp.dll to find the character matching the address (the function in which it is located)

+1
source share

GetExceptionInformation will return an EXCEPTION_POINTERS structure that contains the exception information. The ExceptionRecord element contains the ExceptionAddress member, which is the exception address.

You will need to map this address to the relative location of the module in your code to be useful. You can use GetModuleHandleEx with GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS to get HMODULE (which is also the base address of the module). Then GetModuleInformation can be used to get the actual name of the module in which the exception occurred.

This may not be so useful to you if the error is actually located inside the system DLL. A more complex scheme would be to create a stack trace (using Stackwalk64 in dbghelp) and ignore the top frames that are not in your code.

+1
source share

You can avoid the pain of printing a line to exclude (what happens if you can save the mini-drive but can't format the line without crashes?) By saving the mini-drive instead and using cdb.exe or windbg.exe to extract information about exceptions.

0
source share

All Articles