395{
396
397
399
402
403
404 CONTEXT c = {0};
405 if (context == NULL)
406 {
407#if _WIN32_WINNT <= 0x0501
408 if (hThread == GetCurrentThread())
409#else
410 if (GetThreadId(hThread) == GetCurrentThreadId())
411#endif
412 {
414 }
415 else
416 {
417
418 SuspendThread(hThread);
419 memset(&c, 0, sizeof(CONTEXT));
420 c.ContextFlags = CONTEXT_FULL;
421 if (GetThreadContext(hThread, &c) == FALSE)
422 {
423 ResumeThread(hThread);
424 return NULL;
425 }
426 }
427 }
428 else
429 c = *context;
430
431 STACKFRAME64 sf = {};
432 DWORD imageType;
433
434
435#ifdef _M_IX86
436 imageType = IMAGE_FILE_MACHINE_I386;
437 sf.AddrPC.Offset = c.Eip;
438 sf.AddrPC.Mode = AddrModeFlat;
439 sf.AddrFrame.Offset = c.Ebp;
440 sf.AddrFrame.Mode = AddrModeFlat;
441 sf.AddrStack.Offset = c.Esp;
442 sf.AddrStack.Mode = AddrModeFlat;
443
444#elif _M_X64
445 imageType = IMAGE_FILE_MACHINE_AMD64;
446 sf.AddrPC.Offset = c.Rip;
447 sf.AddrPC.Mode = AddrModeFlat;
448 sf.AddrFrame.Offset = c.Rsp;
449 sf.AddrFrame.Mode = AddrModeFlat;
450 sf.AddrStack.Offset = c.Rsp;
451 sf.AddrStack.Mode = AddrModeFlat;
453#elif _M_IA64
454 imageType = IMAGE_FILE_MACHINE_IA64;
455 sf.AddrPC.Offset = c.StIIP;
456 sf.AddrPC.Mode = AddrModeFlat;
457 sf.AddrFrame.Offset = c.IntSp;
458 sf.AddrFrame.Mode = AddrModeFlat;
459 sf.AddrBStore.Offset = c.RsBSP;
460 sf.AddrBStore.Mode = AddrModeFlat;
461 sf.AddrStack.Offset = c.IntSp;
462 sf.AddrStack.Mode = AddrModeFlat;
463
464#elif defined(_M_ARM64)
465 imageType = IMAGE_FILE_MACHINE_ARM64;
466 sf.AddrPC.Offset = c.Pc;
467 sf.AddrPC.Mode = AddrModeFlat;
468 sf.AddrFrame.Offset = c.Fp;
469 sf.AddrFrame.Mode = AddrModeFlat;
470 sf.AddrStack.Offset = c.Sp;
471 sf.AddrStack.Mode = AddrModeFlat;
472#else
473#error "Platform not supported!"
474#endif
475
476
477 DWORD64 dwDisplayment = 0;
478 PIMAGEHLP_SYMBOL64 pSym = (PIMAGEHLP_SYMBOL64)
new BYTE[
sizeof(IMAGEHLP_SYMBOL64) +
STACKWALK_MAX_NAMELEN];
479 PIMAGEHLP_LINE64 pLine = new IMAGEHLP_LINE64;
480 while (StackWalk64(imageType,
m_hProcess, hThread, &sf, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
481 {
483 ZeroMemory(pLine, sizeof(IMAGEHLP_LINE64));
484
485 pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
487 pLine->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
488
490 ZeroMemory(pCallStack,
sizeof(
STACKINFO));
491 pCallStack->
szFncAddr = sf.AddrPC.Offset;
492 if (sf.AddrPC.Offset != 0)
493 {
494 if(SymGetSymFromAddr64(
m_hProcess, sf.AddrPC.Offset, &dwDisplayment, pSym))
495 {
503 }else
504 {
505
506
507
509 }
510
511 if (SymGetLineFromAddr64(
m_hProcess, sf.AddrPC.Offset, (DWORD*)&dwDisplayment, pLine))
512 {
514 pCallStack->
uFileNum = pLine->LineNumber;
515 }else
516 {
517
518
521 }
522
523
525 if (NULL == pHead)
526 {
527 pHead = pCallStack;
528 pTail = pHead;
529 }else
530 {
531 pTail->
pNext = pCallStack;
532 pTail = pCallStack;
533 }
534 }
535 }
536
537 delete[] pSym;
538 delete pLine;
539
540 return pHead;
541}
TCHAR undName[STACKWALK_MAX_NAMELEN]
Definition StackWalker.h:215
TCHAR szFileName[MAX_PATH]
Definition StackWalker.h:212
TCHAR szFncName[MAX_PATH]
Definition StackWalker.h:213
#define GET_CURRENT_THREAD_CONTEXT(c, contextFlags)
Definition StackWalker.h:278
struct tagSTACKINFO STACKINFO
#define STACKWALK_MAX_NAMELEN
Definition StackWalker.h:164
DWORD64 szFncAddr
Definition StackWalker.h:211
unsigned long uFileNum
Definition StackWalker.h:214
TCHAR undFullName[STACKWALK_MAX_NAMELEN]
Definition StackWalker.h:216
virtual void OutputString(LPCTSTR lpszFormat,...)
Definition StackWalker.cpp:346