Merge pull request #23420 from jtattermusch/win_better_debugging2

Improve windows crash handler for tests
pull/23856/head
Jan Tattermusch 5 years ago committed by GitHub
commit 35f64979da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 83
      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"<<no symbol>>", (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"<<no symbol>>";
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"<<no line info>>";
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();

Loading…
Cancel
Save