Visual Studio unhandled exception stack trace

At work I've got the task to get a stacktrace to a thower of unhandled std exception. The first think I've tried was to print stacktrace from a terminate handler set with std::set_terminate. But I had no lack with this way because the stack is unwinded before std::terminate was called. The solution is to use windows API to get the result.

Three steps to get the stacktrace:



1. Detect unhandled exception

I've found a function SetUnhandledExceptionFilter which allowed me to get context of exception throw. In practice the context is just state of registers of a processor, but this is actually enough to do the thing.
Lets see the function takes a pointer to a handler of this format
The handler gets the struct _EXCEPTION_POINTERS, containing the context and exception signature, as input. It returns instruction what to do with this particular exception case. I return EXCEPTION_CONTINUE_SEARCH because looks like this is kinda default.

2. Get stacktrace as list of offsets in memory

The function with a healthy name "StackWalk" helps us in stepping though the stack. 
It expects a number of argument but don't be scared, in our case we use only 4 of them, the rest are NULL.

Use next function to get necessary information about current process:

MachineType = https://docs.microsoft.com/en-us/windows/desktop/api/wow64apiset/nf-wow64apiset-iswow64process2

hProcess = GetCurrentProcessId()

hThread = GetCurrentThread()

StackFrame = Not as easy
We have to fill this struct for the first frame of stack and this parameter will also be used as output for every next frame. 

Again we don't need every parameter. Take all values from _EXCEPTION_POINTERS structure passed to UnhandledExceptionFilter.
Just provide next 3 values:
AddrPc - from EIP for x86 or RIP for x64
AddrFrame - EBP for x86 or RBP for x64
AddrStack - ESP for x86 or RSP for x64

Fill the reset with default values (NULL or False)

Now call StackWalk in cycle until it return false and record AddrStack adresss every iteration. List of this values is actually a binary stacktrace.

There is also another option is to use "MiniDumpWriteDump"
This gives you a minidump file allowing to get stacktrace and even local variables. Minidump files are opened in visual studio and allows to reproduce error.

LONG WINAPI MyUnhandledExceptionFilter( _In_ struct _EXCEPTION_POINTERS *exceptionInfo ) {
 STACKFRAME64 stackFrame;
 stackFrame.AddrPC = ADDRESS64{ exceptionInfo->ContextRecord->Eip, 0, AddrModeFlat };
 stackFrame.AddrFrame = ADDRESS64{ exceptionInfo->ContextRecord->Ebp, 0, AddrModeFlat };
 stackFrame.AddrStack = ADDRESS64{ exceptionInfo->ContextRecord->Esp, 0, AddrModeFlat };
 stackFrame.FuncTableEntry = NULL;
 stackFrame.Params[0] = 0;
 stackFrame.Far = FALSE;
 stackFrame.Virtual = FALSE;
 stackFrame.Reserved[0] = 0;

 DAVA::Vector stackPointers;

 while (StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &stackFrame, NULL, NULL, NULL, NULL, NULL)) {
  stackPointers.push_back(reinterpret_cast(stackFrame.AddrPC.Offset));
 }

 return EXCEPTION_EXECUTE_HANDLER;
}

3. Stringify

Didn't implemented yet.

Комментарии

  1. Here your most discerning, high-wagering gamers can get pleasure from the perfect in live gaming with excessive most bets and enhanced management at one-to-one, single-player personal tables. Our multi-camera immersive view brings gamers closer to the action by allowing them to comply with each spin of the wheel and motion of the ball. There’s a selection of recreation views and wealthy features similar to Autoplay, extensive statistics from which bets can be placed, chat and the likelihood heaps of|to 로스트아크 keep away from wasting} as much as} 15 favorite bets. Evolution Live Roulette is the most well-liked, genuine and exciting live dealer Roulette available on-line. Slots Empire is one more on-line roulette casino that focuses its name on slots, but they offer a fairly decent roulette library.

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

Siege Up! Editor (beta)

STM32F4 и программный выход в DFU

Git и Yandex.Disk