[DRWTSN32] Improve stack dumping

This commit is contained in:
Mark Jansen 2018-10-21 14:46:44 +02:00
parent f80ec8b822
commit 1fa4e5f29c
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B

View file

@ -2,12 +2,14 @@
* PROJECT: Dr. Watson crash reporter * PROJECT: Dr. Watson crash reporter
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Print a stacktrace * PURPOSE: Print a stacktrace
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) * COPYRIGHT: Copyright 2017,2018 Mark Jansen (mark.jansen@reactos.org)
*/ */
#include "precomp.h" #include "precomp.h"
#include <dbghelp.h> #include <dbghelp.h>
#define STACK_MAX_RECURSION_DEPTH 50
void BeginStackBacktrace(DumpData& data) void BeginStackBacktrace(DumpData& data)
{ {
@ -59,23 +61,28 @@ void PrintStackBacktrace(FILE* output, DumpData& data, ThreadData& thread)
char buf[sizeof(SYMBOL_INFO) + STACKWALK_MAX_NAMELEN] = {0}; char buf[sizeof(SYMBOL_INFO) + STACKWALK_MAX_NAMELEN] = {0};
SYMBOL_INFO* sym = (SYMBOL_INFO *)buf; SYMBOL_INFO* sym = (SYMBOL_INFO *)buf;
IMAGEHLP_MODULE64 Module = { 0 }; IMAGEHLP_MODULE64 Module = { 0 };
LONG RecursionDepth = 0;
sym->SizeOfStruct = sizeof(sym); sym->SizeOfStruct = sizeof(sym);
/* FIXME: Disasm function! */ /* FIXME: dump x bytes at EIP here + disasm it! */
xfprintf(output, NEWLINE "*----> Stack Back Trace <----*" NEWLINE NEWLINE); xfprintf(output, NEWLINE "*----> Stack Back Trace <----*" NEWLINE NEWLINE);
bool first = true; bool first = true;
ULONG_PTR LastFrame = StackFrame.AddrFrame.Offset - 8; while (StackWalk64(MachineType, data.ProcessHandle, thread.Handle, &StackFrame, &thread.Context,
while(StackWalk64(MachineType, data.ProcessHandle, thread.Handle, &StackFrame, &thread.Context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
{ {
if (!StackFrame.AddrPC.Offset) if (StackFrame.AddrPC.Offset == StackFrame.AddrReturn.Offset)
break; {
if (RecursionDepth++ > STACK_MAX_RECURSION_DEPTH)
if (LastFrame >= StackFrame.AddrFrame.Offset) {
break; xfprintf(output, "- Aborting stackwalk -" NEWLINE);
break;
LastFrame = StackFrame.AddrFrame.Offset; }
}
else
{
RecursionDepth = 0;
}
if (first) if (first)
{ {
@ -85,7 +92,7 @@ void PrintStackBacktrace(FILE* output, DumpData& data, ThreadData& thread)
Module.SizeOfStruct = sizeof(Module); Module.SizeOfStruct = sizeof(Module);
DWORD64 ModBase = SymGetModuleBase64(data.ProcessHandle, StackFrame.AddrPC.Offset); DWORD64 ModBase = SymGetModuleBase64(data.ProcessHandle, StackFrame.AddrPC.Offset);
if (!SymGetModuleInfo64(data.ProcessHandle, ModBase, &Module)) if (!ModBase || !SymGetModuleInfo64(data.ProcessHandle, ModBase, &Module))
strcpy(Module.ModuleName, "<nomod>"); strcpy(Module.ModuleName, "<nomod>");
memset(sym, '\0', sizeof(*sym) + STACKWALK_MAX_NAMELEN); memset(sym, '\0', sizeof(*sym) + STACKWALK_MAX_NAMELEN);
@ -93,7 +100,7 @@ void PrintStackBacktrace(FILE* output, DumpData& data, ThreadData& thread)
sym->MaxNameLen = STACKWALK_MAX_NAMELEN; sym->MaxNameLen = STACKWALK_MAX_NAMELEN;
DWORD64 displacement; DWORD64 displacement;
if (!SymFromAddr(data.ProcessHandle, StackFrame.AddrPC.Offset, &displacement, sym)) if (!StackFrame.AddrPC.Offset || !SymFromAddr(data.ProcessHandle, StackFrame.AddrPC.Offset, &displacement, sym))
strcpy(sym->Name, "<nosymbols>"); strcpy(sym->Name, "<nosymbols>");
xfprintf(output, "%p %p %p %p %p %p %s!%s" NEWLINE, xfprintf(output, "%p %p %p %p %p %p %s!%s" NEWLINE,