| 362 | } |
| 363 | |
| 364 | void print_stacktrace_from_context(CONTEXT* ctx) { |
| 365 | HANDLE process = GetCurrentProcess(); |
| 366 | HANDLE thread = GetCurrentThread(); |
| 367 | init_symbols(); |
| 368 | |
| 369 | CONTEXT ctxCopy = *ctx; |
| 370 | |
| 371 | STACKFRAME64 frame; |
| 372 | memset(&frame, 0, sizeof(frame)); |
| 373 | #if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__) |
| 374 | DWORD machineType = IMAGE_FILE_MACHINE_AMD64; |
| 375 | frame.AddrPC.Offset = ctxCopy.Rip; |
| 376 | frame.AddrPC.Mode = AddrModeFlat; |
| 377 | frame.AddrFrame.Offset = ctxCopy.Rbp; |
| 378 | frame.AddrFrame.Mode = AddrModeFlat; |
| 379 | frame.AddrStack.Offset = ctxCopy.Rsp; |
| 380 | frame.AddrStack.Mode = AddrModeFlat; |
| 381 | #else |
| 382 | DWORD machineType = IMAGE_FILE_MACHINE_I386; |
| 383 | frame.AddrPC.Offset = ctxCopy.Eip; |
| 384 | frame.AddrPC.Mode = AddrModeFlat; |
| 385 | frame.AddrFrame.Offset = ctxCopy.Ebp; |
| 386 | frame.AddrFrame.Mode = AddrModeFlat; |
| 387 | frame.AddrStack.Offset = ctxCopy.Esp; |
| 388 | frame.AddrStack.Mode = AddrModeFlat; |
| 389 | #endif |
| 390 | |
| 391 | printf("Stack trace (from exception context via StackWalk64):\n\n"); |
| 392 | |
| 393 | #if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__) |
| 394 | if (ctxCopy.Rip == 0 && ctxCopy.Rsp != 0) { |
| 395 | printf("#0 0x0000000000000000 [<null>] -- null function pointer call\n"); |
| 396 | DWORD64 retAddr = 0; |
| 397 | SIZE_T bytesRead = 0; |
| 398 | if (ReadProcessMemory(process, (LPCVOID)ctxCopy.Rsp, &retAddr, |
| 399 | sizeof(retAddr), &bytesRead) && bytesRead == sizeof(retAddr)) { |
| 400 | ctxCopy.Rip = retAddr; |
| 401 | ctxCopy.Rsp += sizeof(DWORD64); |
| 402 | memset(&frame, 0, sizeof(frame)); |
| 403 | frame.AddrPC.Offset = ctxCopy.Rip; |
| 404 | frame.AddrPC.Mode = AddrModeFlat; |
| 405 | frame.AddrFrame.Offset = ctxCopy.Rbp; |
| 406 | frame.AddrFrame.Mode = AddrModeFlat; |
| 407 | frame.AddrStack.Offset = ctxCopy.Rsp; |
| 408 | frame.AddrStack.Mode = AddrModeFlat; |
| 409 | } |
| 410 | } |
| 411 | #endif |
| 412 | |
| 413 | for (int i = 0; i < 100; i++) { |
| 414 | if (!StackWalk64(machineType, process, thread, &frame, &ctxCopy, |
| 415 | nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr)) { |
| 416 | break; |
| 417 | } |
| 418 | |
| 419 | if (frame.AddrPC.Offset == 0) { |
| 420 | break; |
| 421 | } |
no test coverage detected