diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 391467ba789..3b5e77c86d7 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -61,45 +61,7 @@ static unsigned seed(void) { return (unsigned)_getpid(); } #pragma comment(lib, "dbghelp.lib") #endif -static void print_current_stack() { - typedef USHORT(WINAPI * CaptureStackBackTraceType)( - __in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG); - CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress( - LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace")); - - if (func == NULL) return; // WOE 29.SEP.2010 - -// Quote from Microsoft Documentation: -// ## Windows Server 2003 and Windows XP: -// ## The sum of the FramesToSkip and FramesToCapture parameters must be less -// than 63. -#define MAX_CALLERS 62 - - void* callers_stack[MAX_CALLERS]; - unsigned short frames; - SYMBOL_INFOW* symbol; - HANDLE process; - process = GetCurrentProcess(); - SymInitialize(process, NULL, TRUE); - frames = (func)(0, MAX_CALLERS, callers_stack, NULL); - symbol = - (SYMBOL_INFOW*)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1); - symbol->MaxNameLen = 255; - symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); - - const unsigned short MAX_CALLERS_SHOWN = 32; - frames = frames < MAX_CALLERS_SHOWN ? frames : MAX_CALLERS_SHOWN; - for (unsigned int i = 0; i < frames; i++) { - SymFromAddrW(process, (DWORD64)(callers_stack[i]), 0, symbol); - fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X\n", i, - (DWORD64)callers_stack[i], symbol->Name, (DWORD64)symbol->Address); - fflush(stderr); - } - - free(symbol); -} - -static void print_stack_from_context(CONTEXT c) { +static void print_stack_from_context(HANDLE thread, CONTEXT c) { STACKFRAME s; // in/out stackframe memset(&s, 0, sizeof(s)); DWORD imageType; @@ -135,26 +97,51 @@ static void print_stack_from_context(CONTEXT c) { #endif HANDLE process = GetCurrentProcess(); - HANDLE thread = GetCurrentThread(); SYMBOL_INFOW* symbol = (SYMBOL_INFOW*)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); - while (StackWalk(imageType, process, thread, &s, &c, 0, - SymFunctionTableAccess, SymGetModuleBase, 0)) { - BOOL has_symbol = - SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol); - fwprintf( - stderr, L"*** %016I64X %ls - %016I64X\n", (DWORD64)(s.AddrPC.Offset), - has_symbol ? symbol->Name : L"<>", (DWORD64)symbol->Address); + const unsigned short MAX_CALLERS_SHOWN = + 8192; // avoid flooding the stderr if stacktrace is way too long + for (int frame = 0; frame < MAX_CALLERS_SHOWN && + StackWalk(imageType, process, thread, &s, &c, 0, + SymFunctionTableAccess, SymGetModuleBase, 0); + frame++) { + PWSTR symbol_name = L"<>"; + DWORD64 symbol_address = 0; + if (SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol)) { + symbol_name = symbol->Name; + symbol_address = (DWORD64)symbol->Address; + } + + PWSTR file_name = L"<>"; + int line_number = 0; + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + DWORD displacement = 0; + if (SymGetLineFromAddrW64(process, (DWORD64)(s.AddrPC.Offset), + &displacement, &line)) { + file_name = line.FileName; + line_number = (int)line.LineNumber; + } + + fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X (%ls:%d)\n", frame, + (DWORD64)(s.AddrPC.Offset), symbol_name, symbol_address, file_name, + line_number); fflush(stderr); } free(symbol); } +static void print_current_stack() { + CONTEXT context; + RtlCaptureContext(&context); + print_stack_from_context(GetCurrentThread(), context); +} + static LONG crash_handler(struct _EXCEPTION_POINTERS* ex_info) { fprintf(stderr, "Exception handler called, dumping information\n"); bool try_to_print_stack = true; @@ -168,7 +155,7 @@ static LONG crash_handler(struct _EXCEPTION_POINTERS* ex_info) { exrec = exrec->ExceptionRecord; } if (try_to_print_stack) { - print_stack_from_context(*ex_info->ContextRecord); + print_stack_from_context(GetCurrentThread(), *ex_info->ContextRecord); } if (IsDebuggerPresent()) { __debugbreak();