stackwalker.cpp
Go to the documentation of this file.
1 
2 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions, and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions, and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the names of the copyright holders nor the names of their contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
26 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
28 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
29 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
30 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
31 //
32 
33 
34 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
35 // All rights reserved.
36 //
37 // Redistribution and use in source and binary forms, with or without modification,
38 // are permitted provided that the following conditions are met:
39 //
40 // 1. Redistributions of source code must retain the above copyright notice,
41 // this list of conditions, and the following disclaimer.
42 //
43 // 2. Redistributions in binary form must reproduce the above copyright notice,
44 // this list of conditions, and the following disclaimer in the documentation
45 // and/or other materials provided with the distribution.
46 //
47 // 3. Neither the names of the copyright holders nor the names of their contributors
48 // may be used to endorse or promote products derived from this software without
49 // specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
52 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
53 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
54 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
58 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
60 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
61 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
62 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
63 //
64 
65 /**********************************************************************
66 
67  StackWalker.cpp
68 
69 
70  History:
71  2005-07-27 v1 - First public release on http://www.codeproject.com/
72  http://www.codeproject.com/threads/StackWalker.asp
73  2005-07-28 v2 - Changed the params of the constructor and ShowCallstack
74  (to simplify the usage)
75  2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL
76  (should also be enough)
77  - Changed to compile correctly with the PSDK of VC7.0
78  (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined:
79  it uses LPSTR instead of LPCSTR as first paremeter)
80  - Added declarations to support VC5/6 without using 'dbghelp.h'
81  - Added a 'pUserData' member to the ShowCallstack function and the
82  PReadProcessMemoryRoutine declaration (to pass some user-defined data,
83  which can be used in the readMemoryFunction-callback)
84  2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default
85  - Added example for doing an exception-callstack-walking in main.cpp
86  (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268)
87  2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse!
88 
89  **********************************************************************/
90 
91 #ifndef __GNUC__
92 
93 #include <windows.h>
94 #include <tchar.h>
95 #include <stdio.h>
96 #pragma comment(lib, "version.lib") // for "VerQueryValue"
97 
98 #include "stackwalker.h"
99 
100 
101 // If VC7 and later, then use the shipped 'dbghelp.h'-file
102 #if _MSC_VER >= 1300
103 #pragma warning(push)
104 #pragma warning(disable: 4091)
105 #include <dbghelp.h>
106 #pragma warning(pop)
107 #else
108 // inline the important dbghelp.h-declarations...
109 typedef enum
110 {
111  SymNone = 0,
112  SymCoff,
113  SymCv,
114  SymPdb,
115  SymExport,
116  SymDeferred,
117  SymSym,
118  SymDia,
119  SymVirtual,
121 } SYM_TYPE;
122 
123 typedef struct _IMAGEHLP_LINE64
124 {
125  DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
126  PVOID Key; // internal
127  DWORD LineNumber; // line number in file
128  PCHAR FileName; // full filename
129  DWORD64 Address; // first instruction of line
131 
132 typedef struct _IMAGEHLP_MODULE64
133 {
134  DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
135  DWORD64 BaseOfImage; // base load address of module
136  DWORD ImageSize; // virtual size of the loaded module
137  DWORD TimeDateStamp; // date/time stamp from pe header
138  DWORD CheckSum; // checksum from the pe header
139  DWORD NumSyms; // number of symbols in the symbol table
140  SYM_TYPE SymType; // type of symbols loaded
141  CHAR ModuleName[32]; // module name
142  CHAR ImageName[256]; // image name
143  CHAR LoadedImageName[256]; // symbol file name
145 
146 typedef struct _IMAGEHLP_SYMBOL64
147 {
148  DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64)
149  DWORD64 Address; // virtual address including dll base address
150  DWORD Size; // estimated size of symbol, can be zero
151  DWORD Flags; // info about the symbols, see the SYMF defines
152  DWORD MaxNameLength; // maximum size of symbol name in 'Name'
153  CHAR Name[1]; // symbol name (null terminated string)
155 
156 typedef enum
157 {
162 } ADDRESS_MODE;
163 
164 typedef struct _tagADDRESS64
165 {
167  WORD Segment;
170 
171 typedef struct _KDHELP64
172 {
182 } KDHELP64, *PKDHELP64;
183 
184 typedef struct _tagSTACKFRAME64
185 {
186  ADDRESS64 AddrPC; // program counter
187  ADDRESS64 AddrReturn; // return address
188  ADDRESS64 AddrFrame; // frame pointer
189  ADDRESS64 AddrStack; // stack pointer
190  ADDRESS64 AddrBStore; // backing store pointer
191  PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
192  DWORD64 Params[4]; // possible arguments to the function
193  BOOL Far; // WOW far call
194  BOOL Virtual; // is this a virtual frame?
198 
200  HANDLE hProcess,
201  DWORD64 qwBaseAddress,
202  PVOID lpBuffer,
203  DWORD nSize,
204  LPDWORD lpNumberOfBytesRead
205 );
206 
207 typedef PVOID(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE64)(
208  HANDLE hProcess,
209  DWORD64 AddrBase
210 );
211 
213  HANDLE hProcess,
214  DWORD64 Address
215 );
216 
218  HANDLE hProcess,
219  HANDLE hThread,
220  LPADDRESS64 lpaddr
221 );
222 
223 #define SYMOPT_CASE_INSENSITIVE 0x00000001
224 #define SYMOPT_UNDNAME 0x00000002
225 #define SYMOPT_DEFERRED_LOADS 0x00000004
226 #define SYMOPT_NO_CPP 0x00000008
227 #define SYMOPT_LOAD_LINES 0x00000010
228 #define SYMOPT_OMAP_FIND_NEAREST 0x00000020
229 #define SYMOPT_LOAD_ANYTHING 0x00000040
230 #define SYMOPT_IGNORE_CVREC 0x00000080
231 #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
232 #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
233 #define SYMOPT_EXACT_SYMBOLS 0x00000400
234 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
235 #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
236 #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
237 #define SYMOPT_PUBLICS_ONLY 0x00004000
238 #define SYMOPT_NO_PUBLICS 0x00008000
239 #define SYMOPT_AUTO_PUBLICS 0x00010000
240 #define SYMOPT_NO_IMAGE_SEARCH 0x00020000
241 #define SYMOPT_SECURE 0x00040000
242 #define SYMOPT_DEBUG 0x80000000
243 #define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
244 #define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
245 #endif // _MSC_VER < 1300
246 
247 // Some missing defines (for VC5/6):
248 #ifndef INVALID_FILE_ATTRIBUTES
249  #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
250 #endif
251 
252 // secure-CRT_functions are only available starting with VC8
253 #if _MSC_VER < 1400
254  #define strcpy_s strcpy
255  #define strcat_s(dst, len, src) strcat(dst, src)
256  #define _snprintf_s _snprintf
257  #define _tcscat_s _tcscat
258 #endif
259 
260 // Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
261 #define USED_CONTEXT_FLAGS CONTEXT_FULL
262 
264 {
265 public:
266  StackWalkerInternal(StackWalker* parent, HANDLE hProcess)
267  {
268  m_parent = parent;
269  m_hDbhHelp = NULL;
270  pSC = NULL;
271  m_hProcess = hProcess;
272  m_szSymPath = NULL;
273  pSFTA = NULL;
274  pSGLFA = NULL;
275  pSGMB = NULL;
276  pSGMI = NULL;
277  pSGO = NULL;
278  pSGSFA = NULL;
279  pSI = NULL;
280  pSLM = NULL;
281  pSSO = NULL;
282  pSW = NULL;
283  pUDSN = NULL;
284  pSGSP = NULL;
285  }
286 
288  {
289  if (pSC != NULL)
290  pSC(m_hProcess); // SymCleanup
291  if (m_hDbhHelp != NULL)
292  FreeLibrary(m_hDbhHelp);
293  m_hDbhHelp = NULL;
294  m_parent = NULL;
295  if (m_szSymPath != NULL)
296  free(m_szSymPath);
297  m_szSymPath = NULL;
298  }
299 
300  BOOL Init(LPCSTR szSymPath)
301  {
302  if (m_parent == NULL)
303  return FALSE;
304  // Dynamically load the Entry-Points for dbghelp.dll:
305  // First try to load the newsest one from
306  TCHAR szTemp[4096];
307  // But before wqe do this, we first check if the ".local" file exists
308  if (GetModuleFileName(NULL, szTemp, 4096) > 0)
309  {
310  _tcscat_s(szTemp, _T(".local"));
311  if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES)
312  {
313  // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows"
314  if (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0)
315  {
316  _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll"));
317  // now check if the file exists:
318  if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
319  m_hDbhHelp = LoadLibrary(szTemp);
320  }
321  // Still not found? Then try to load the 64-Bit version:
322  if ((m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0))
323  {
324  _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll"));
325  if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
326  m_hDbhHelp = LoadLibrary(szTemp);
327  }
328  }
329  }
330  if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one
331  m_hDbhHelp = LoadLibrary(_T("dbghelp.dll"));
332  if (m_hDbhHelp == NULL)
333  return FALSE;
334  pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize");
335  pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup");
336 
337  pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64");
338  pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions");
339  pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions");
340 
341  pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64");
342  pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64");
343  pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64");
344  pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64");
345  //pSGMI_V3 = (tSGMI_V3) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" );
346  pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64");
347  pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName");
348  pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64");
349  pSGSP = (tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath");
350 
351  if (pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL ||
352  pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL ||
353  pSW == NULL || pUDSN == NULL || pSLM == NULL)
354  {
355  FreeLibrary(m_hDbhHelp);
356  m_hDbhHelp = NULL;
357  pSC = NULL;
358  return FALSE;
359  }
360 
361  // SymInitialize
362  if (szSymPath != NULL)
363  m_szSymPath = _strdup(szSymPath);
364  if (pSI(m_hProcess, m_szSymPath, FALSE) == FALSE)
365  m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0);
366 
367  DWORD symOptions = pSGO(); // SymGetOptions
368  symOptions |= SYMOPT_LOAD_LINES;
369  symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
370  //symOptions |= SYMOPT_NO_PROMPTS;
371  // SymSetOptions
372  symOptions = pSSO(symOptions);
373 
374  char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
375  if (pSGSP != NULL)
376  {
378  m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0);
379  }
380  char szUserName[1024] = {0};
381  DWORD dwSize = 1024;
382  GetUserNameA(szUserName, &dwSize);
383  m_parent->OnSymInit(buf, symOptions, szUserName);
384 
385  return TRUE;
386  }
387 
389 
390  HMODULE m_hDbhHelp;
391  HANDLE m_hProcess;
392  LPSTR m_szSymPath;
393 
394  /* typedef struct IMAGEHLP_MODULE64_V3 {
395  DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
396  DWORD64 BaseOfImage; // base load address of module
397  DWORD ImageSize; // virtual size of the loaded module
398  DWORD TimeDateStamp; // date/time stamp from pe header
399  DWORD CheckSum; // checksum from the pe header
400  DWORD NumSyms; // number of symbols in the symbol table
401  SYM_TYPE SymType; // type of symbols loaded
402  CHAR ModuleName[32]; // module name
403  CHAR ImageName[256]; // image name
404  // new elements: 07-Jun-2002
405  CHAR LoadedImageName[256]; // symbol file name
406  CHAR LoadedPdbName[256]; // pdb file name
407  DWORD CVSig; // Signature of the CV record in the debug directories
408  CHAR CVData[MAX_PATH * 3]; // Contents of the CV record
409  DWORD PdbSig; // Signature of PDB
410  GUID PdbSig70; // Signature of PDB (VC 7 and up)
411  DWORD PdbAge; // DBI age of pdb
412  BOOL PdbUnmatched; // loaded an unmatched pdb
413  BOOL DbgUnmatched; // loaded an unmatched dbg
414  BOOL LineNumbers; // we have line number information
415  BOOL GlobalSymbols; // we have internal symbol information
416  BOOL TypeInfo; // we have type information
417  // new elements: 17-Dec-2003
418  BOOL SourceIndexed; // pdb supports source server
419  BOOL Publics; // contains public symbols
420  };
421  */
423  {
424  DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
425  DWORD64 BaseOfImage; // base load address of module
426  DWORD ImageSize; // virtual size of the loaded module
427  DWORD TimeDateStamp; // date/time stamp from pe header
428  DWORD CheckSum; // checksum from the pe header
429  DWORD NumSyms; // number of symbols in the symbol table
430  SYM_TYPE SymType; // type of symbols loaded
431  CHAR ModuleName[32]; // module name
432  CHAR ImageName[256]; // image name
433  CHAR LoadedImageName[256]; // symbol file name
434  };
435 
436 
437  // SymCleanup()
438  typedef BOOL (__stdcall* tSC)(IN HANDLE hProcess);
440 
441  // SymFunctionTableAccess64()
442  typedef PVOID(__stdcall* tSFTA)(HANDLE hProcess, DWORD64 AddrBase);
444 
445  // SymGetLineFromAddr64()
446  typedef BOOL (__stdcall* tSGLFA)(IN HANDLE hProcess, IN DWORD64 dwAddr,
447  OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line);
449 
450  // SymGetModuleBase64()
451  typedef DWORD64(__stdcall* tSGMB)(IN HANDLE hProcess, IN DWORD64 dwAddr);
453 
454  // SymGetModuleInfo64()
455  typedef BOOL (__stdcall* tSGMI)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V2* ModuleInfo);
457 
458  // // SymGetModuleInfo64()
459  // typedef BOOL (__stdcall *tSGMI_V3)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo );
460  // tSGMI_V3 pSGMI_V3;
461 
462  // SymGetOptions()
463  typedef DWORD (__stdcall* tSGO)(VOID);
465 
466  // SymGetSymFromAddr64()
467  typedef BOOL (__stdcall* tSGSFA)(IN HANDLE hProcess, IN DWORD64 dwAddr,
468  OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol);
470 
471  // SymInitialize()
472  typedef BOOL (__stdcall* tSI)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess);
474 
475  // SymLoadModule64()
476  typedef DWORD64(__stdcall* tSLM)(IN HANDLE hProcess, IN HANDLE hFile,
477  IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll);
479 
480  // SymSetOptions()
481  typedef DWORD (__stdcall* tSSO)(IN DWORD SymOptions);
483 
484  // StackWalk64()
485  typedef BOOL (__stdcall* tSW)(
486  DWORD MachineType,
487  HANDLE hProcess,
488  HANDLE hThread,
489  LPSTACKFRAME64 StackFrame,
490  PVOID ContextRecord,
491  PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
492  PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
493  PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
494  PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
496 
497  // UnDecorateSymbolName()
498  typedef DWORD (__stdcall* tUDSN)(PCSTR DecoratedName, PSTR UnDecoratedName,
499  DWORD UndecoratedLength, DWORD Flags);
501 
502  typedef BOOL (__stdcall* tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength);
504 
505 
506 private:
507  // **************************************** ToolHelp32 ************************
508 #define MAX_MODULE_NAME32 255
509 #define TH32CS_SNAPMODULE 0x00000008
510 #pragma pack( push, 8 )
511  typedef struct tagMODULEENTRY32
512  {
513  DWORD dwSize;
514  DWORD th32ModuleID; // This module
515  DWORD th32ProcessID; // owning process
516  DWORD GlblcntUsage; // Global usage count on the module
517  DWORD ProccntUsage; // Module usage count in th32ProcessID's context
518  BYTE* modBaseAddr; // Base address of module in th32ProcessID's context
519  DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
520  HMODULE hModule; // The hModule of this module in th32ProcessID's context
522  char szExePath[MAX_PATH];
523  } MODULEENTRY32;
526 #pragma pack( pop )
527 
528  BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid)
529  {
530 
531  // CreateToolhelp32Snapshot()
532  typedef HANDLE(__stdcall * tCT32S)(DWORD dwFlags, DWORD th32ProcessID);
533  // Module32First()
534  typedef BOOL (__stdcall * tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
535  // Module32Next()
536  typedef BOOL (__stdcall * tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
537 
538  // try both dlls...
539  const TCHAR* dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") };
540  HINSTANCE hToolhelp = NULL;
541  tCT32S pCT32S = NULL;
542  tM32F pM32F = NULL;
543  tM32N pM32N = NULL;
544 
545  HANDLE hSnap;
546  MODULEENTRY32 me;
547  me.dwSize = sizeof(me);
548  bool keepGoing;
549  size_t i;
550 
551  for (i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
552  {
553  hToolhelp = LoadLibrary(dllname[i]);
554  if (hToolhelp == NULL)
555  continue;
556  pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
557  pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First");
558  pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next");
559  if ((pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL))
560  break; // found the functions!
561  FreeLibrary(hToolhelp);
562  hToolhelp = NULL;
563  }
564 
565  if (hToolhelp == NULL)
566  return FALSE;
567 
568  hSnap = pCT32S(TH32CS_SNAPMODULE, pid);
569  if (hSnap == (HANDLE) - 1)
570  return FALSE;
571 
572  keepGoing = !!pM32F(hSnap, &me);
573  int cnt = 0;
574  while (keepGoing)
575  {
576  this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize);
577  cnt++;
578  keepGoing = !!pM32N(hSnap, &me);
579  }
580  CloseHandle(hSnap);
581  FreeLibrary(hToolhelp);
582  if (cnt <= 0)
583  return FALSE;
584  return TRUE;
585  } // GetModuleListTH32
586 
587  // **************************************** PSAPI ************************
588  typedef struct _MODULEINFO
589  {
590  LPVOID lpBaseOfDll;
591  DWORD SizeOfImage;
592  LPVOID EntryPoint;
594 
595  BOOL GetModuleListPSAPI(HANDLE hProcess)
596  {
597  // EnumProcessModules()
598  typedef BOOL (__stdcall * tEPM)(HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
599  // GetModuleFileNameEx()
600  typedef DWORD (__stdcall * tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
601  // GetModuleBaseName()
602  typedef DWORD (__stdcall * tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
603  // GetModuleInformation()
604  typedef BOOL (__stdcall * tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize);
605 
606  HINSTANCE hPsapi;
607  tEPM pEPM;
608  tGMFNE pGMFNE;
609  tGMBN pGMBN;
610  tGMI pGMI;
611 
612  DWORD i;
613  //ModuleEntry e;
614  DWORD cbNeeded;
615  MODULEINFO mi;
616  HMODULE* hMods;
617  char* tt;
618  char* tt2;
619  const SIZE_T TTBUFLEN = 8096;
620  int cnt = 0;
621 
622  hPsapi = LoadLibrary(_T("psapi.dll"));
623  if (hPsapi == NULL)
624  return FALSE;
625 
626  pEPM = (tEPM) GetProcAddress(hPsapi, "EnumProcessModules");
627  pGMFNE = (tGMFNE) GetProcAddress(hPsapi, "GetModuleFileNameExA");
628  pGMBN = (tGMFNE) GetProcAddress(hPsapi, "GetModuleBaseNameA");
629  pGMI = (tGMI) GetProcAddress(hPsapi, "GetModuleInformation");
630  if ((pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL))
631  {
632  // we couldnt find all functions
633  FreeLibrary(hPsapi);
634  return FALSE;
635  }
636 
637  hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof(HMODULE)));
638  tt = (char*) malloc(sizeof(char) * TTBUFLEN);
639  tt2 = (char*) malloc(sizeof(char) * TTBUFLEN);
640  if ((hMods == NULL) || (tt == NULL) || (tt2 == NULL))
641  goto cleanup;
642 
643  if (! pEPM(hProcess, hMods, TTBUFLEN, &cbNeeded))
644  {
645  //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle );
646  goto cleanup;
647  }
648 
649  if (cbNeeded > TTBUFLEN)
650  {
651  //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) );
652  goto cleanup;
653  }
654 
655  for (i = 0; i < cbNeeded / sizeof hMods[0]; i++)
656  {
657  // base address, size
658  pGMI(hProcess, hMods[i], &mi, sizeof mi);
659  // image file name
660  tt[0] = 0;
661  pGMFNE(hProcess, hMods[i], tt, TTBUFLEN);
662  // module name
663  tt2[0] = 0;
664  pGMBN(hProcess, hMods[i], tt2, TTBUFLEN);
665 
666  DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage);
667  if (dwRes != ERROR_SUCCESS)
668  m_parent->OnDbgHelpErr("LoadModule", dwRes, 0);
669  cnt++;
670  }
671 
672 cleanup:
673  FreeLibrary(hPsapi);
674  if (tt2 != NULL)
675  free(tt2);
676  if (tt != NULL)
677  free(tt);
678  if (hMods != NULL)
679  free(hMods);
680 
681  return (cnt != 0) ? TRUE : FALSE;
682  } // GetModuleListPSAPI
683 
684  DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size)
685  {
686  CHAR* szImg = _strdup(img);
687  CHAR* szMod = _strdup(mod);
688  DWORD result = ERROR_SUCCESS;
689  if ((szImg == NULL) || (szMod == NULL))
690  result = ERROR_NOT_ENOUGH_MEMORY;
691  else if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0)
692  result = GetLastError();
693  ULONGLONG fileVersion = 0;
694  if ((m_parent != NULL) && (szImg != NULL))
695  {
696  // try to retrive the file-version:
698  {
699  VS_FIXEDFILEINFO* fInfo = NULL;
700  DWORD dwHandle;
701  DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle);
702  if (dwSize > 0)
703  {
704  LPVOID vData = malloc(dwSize);
705  if (vData != NULL)
706  {
707  if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0)
708  {
709  UINT len;
710  TCHAR szSubBlock[] = _T("\\");
711  if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) != 0)
712  fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32);
713  }
714  free(vData);
715  }
716  }
717  }
718 
719  // Retrieve some additional-infos about the module
720  IMAGEHLP_MODULE64_V2 Module;
721  const char* szSymType = "-unknown-";
722  if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE)
723  {
724  switch (Module.SymType)
725  {
726  case SymNone:
727  szSymType = "-nosymbols-";
728  break;
729  case SymCoff:
730  szSymType = "COFF";
731  break;
732  case SymCv:
733  szSymType = "CV";
734  break;
735  case SymPdb:
736  szSymType = "PDB";
737  break;
738  case SymExport:
739  szSymType = "-exported-";
740  break;
741  case SymDeferred:
742  szSymType = "-deferred-";
743  break;
744  case SymSym:
745  szSymType = "SYM";
746  break;
747  case SymVirtual:
748  szSymType = "Virtual";
749  break;
750  case SymDia:
751  szSymType = "DIA";
752  break;
753  }
754  }
755  m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, Module.LoadedImageName, fileVersion);
756  }
757  if (szImg != NULL)
758  free(szImg);
759  if (szMod != NULL)
760  free(szMod);
761  return result;
762  }
763 public:
764  BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId)
765  {
766  // first try toolhelp32
767  if (GetModuleListTH32(hProcess, dwProcessId))
768  return TRUE;
769  // then try psapi
770  return GetModuleListPSAPI(hProcess);
771  }
772 
773 
774  BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V2* pModuleInfo)
775  {
776  if (pSGMI == NULL)
777  {
778  SetLastError(ERROR_DLL_INIT_FAILED);
779  return FALSE;
780  }
781  // First try to use the larger ModuleInfo-Structure
782  // memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3));
783  // pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3);
784  // if (this->pSGMI_V3 != NULL)
785  // {
786  // if (this->pSGMI_V3(hProcess, baseAddr, pModuleInfo) != FALSE)
787  // return TRUE;
788  // // check if the parameter was wrong (size is bad...)
789  // if (GetLastError() != ERROR_INVALID_PARAMETER)
790  // return FALSE;
791  // }
792  // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)...
793  pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
794  void* pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites...
795  if (pData == NULL)
796  {
797  SetLastError(ERROR_NOT_ENOUGH_MEMORY);
798  return FALSE;
799  }
800  memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2));
801  if (pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V2*) pData) != FALSE)
802  {
803  // only copy as much memory as is reserved...
804  memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2));
805  pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
806  free(pData);
807  return TRUE;
808  }
809  free(pData);
810  SetLastError(ERROR_DLL_INIT_FAILED);
811  return FALSE;
812  }
813 };
814 
815 // #############################################################
816 StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess)
817 {
818  m_options = (int) OptionsAll;
819  m_modulesLoaded = FALSE;
820  m_hProcess = hProcess;
821  m_sw = new StackWalkerInternal(this, m_hProcess);
822  m_dwProcessId = dwProcessId;
823  m_szSymPath = NULL;
824 }
825 StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
826 {
827  m_options = options;
828  m_modulesLoaded = FALSE;
829  m_hProcess = hProcess;
830  m_sw = new StackWalkerInternal(this, m_hProcess);
831  m_dwProcessId = dwProcessId;
832  if (szSymPath != NULL)
833  {
834  m_szSymPath = _strdup(szSymPath);
835  m_options |= (int) SymBuildPath;
836  }
837  else
838  m_szSymPath = NULL;
839 }
840 
842 {
843  if (m_szSymPath != NULL)
844  free(m_szSymPath);
845  m_szSymPath = NULL;
846  if (m_sw != NULL)
847  delete m_sw;
848  m_sw = NULL;
849 }
850 
852 {
853  if (m_sw == NULL)
854  {
855  SetLastError(ERROR_DLL_INIT_FAILED);
856  return FALSE;
857  }
858  if (m_modulesLoaded != FALSE)
859  return TRUE;
860 
861  // Build the sym-path:
862  char* szSymPath = NULL;
863  if ((m_options & (int) SymBuildPath) != 0)
864  {
865  const size_t nSymPathLen = 4096;
866  szSymPath = (char*) malloc(nSymPathLen);
867  if (szSymPath == NULL)
868  {
869  SetLastError(ERROR_NOT_ENOUGH_MEMORY);
870  return FALSE;
871  }
872  szSymPath[0] = 0;
873  // Now first add the (optional) provided sympath:
874  if (m_szSymPath != NULL)
875  {
876  strcat_s(szSymPath, nSymPathLen, m_szSymPath);
877  strcat_s(szSymPath, nSymPathLen, ";");
878  }
879 
880  strcat_s(szSymPath, nSymPathLen, ".;");
881 
882  const size_t nTempLen = 1024;
883  char szTemp[nTempLen];
884  // Now add the current directory:
885  if (GetCurrentDirectoryA(nTempLen, szTemp) > 0)
886  {
887  szTemp[nTempLen - 1] = 0;
888  strcat_s(szSymPath, nSymPathLen, szTemp);
889  strcat_s(szSymPath, nSymPathLen, ";");
890  }
891 
892  // Now add the path for the main-module:
893  if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0)
894  {
895  szTemp[nTempLen - 1] = 0;
896  for (char* p = (szTemp + strlen(szTemp) - 1); p >= szTemp; --p)
897  {
898  // locate the rightmost path separator
899  if ((*p == '\\') || (*p == '/') || (*p == ':'))
900  {
901  *p = 0;
902  break;
903  }
904  } // for (search for path separator...)
905  if (strlen(szTemp) > 0)
906  {
907  strcat_s(szSymPath, nSymPathLen, szTemp);
908  strcat_s(szSymPath, nSymPathLen, ";");
909  }
910  }
911  if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0)
912  {
913  szTemp[nTempLen - 1] = 0;
914  strcat_s(szSymPath, nSymPathLen, szTemp);
915  strcat_s(szSymPath, nSymPathLen, ";");
916  }
917  if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0)
918  {
919  szTemp[nTempLen - 1] = 0;
920  strcat_s(szSymPath, nSymPathLen, szTemp);
921  strcat_s(szSymPath, nSymPathLen, ";");
922  }
923  if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0)
924  {
925  szTemp[nTempLen - 1] = 0;
926  strcat_s(szSymPath, nSymPathLen, szTemp);
927  strcat_s(szSymPath, nSymPathLen, ";");
928  // also add the "system32"-directory:
929  strcat_s(szTemp, nTempLen, "\\system32");
930  strcat_s(szSymPath, nSymPathLen, szTemp);
931  strcat_s(szSymPath, nSymPathLen, ";");
932  }
933 
934  if ((m_options & (int) SymBuildPath) != 0)
935  {
936  if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0)
937  {
938  szTemp[nTempLen - 1] = 0;
939  strcat_s(szSymPath, nSymPathLen, "SRV*");
940  strcat_s(szSymPath, nSymPathLen, szTemp);
941  strcat_s(szSymPath, nSymPathLen, "\\websymbols");
942  strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;");
943  }
944  else
945  strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;");
946  }
947  }
948 
949  // First Init the whole stuff...
950  BOOL bRet = m_sw->Init(szSymPath);
951  if (szSymPath != NULL)
952  {
953  free(szSymPath);
954  // szSymPath = NULL;
955  }
956  if (bRet == FALSE)
957  {
958  this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0);
959  SetLastError(ERROR_DLL_INIT_FAILED);
960  return FALSE;
961  }
962 
964  if (bRet != FALSE)
965  m_modulesLoaded = TRUE;
966  return bRet;
967 }
968 
969 
970 // The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction
971 // This has to be done due to a problem with the "hProcess"-parameter in x64...
972 // Because this class is in no case multi-threading-enabled (because of the limitations
973 // of dbghelp.dll) it is "safe" to use a static-variable
975 static LPVOID s_readMemoryFunction_UserData = NULL;
976 
977 #ifdef _MSC_VER
978  #pragma warning(disable : 4748)
979 #endif
980 
981 BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT* context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData)
982 {
983  CONTEXT c;;
984  CallstackEntry csEntry;
985  IMAGEHLP_SYMBOL64* pSym = NULL;
987  IMAGEHLP_LINE64 Line;
988  int frameNum;
989 
990  if (m_modulesLoaded == FALSE)
991  {
992  OnOutput("************* Loaded Modules *************");
993  this->LoadModules(); // ignore the result...
994  OnOutput("************* Callstack *************");
995  }
996 
997  if (m_sw->m_hDbhHelp == NULL)
998  {
999  SetLastError(ERROR_DLL_INIT_FAILED);
1000  return FALSE;
1001  }
1002 
1003  s_readMemoryFunction = readMemoryFunction;
1004  s_readMemoryFunction_UserData = pUserData;
1005 
1006  if (context == NULL)
1007  {
1008  // If no context is provided, capture the context
1009  if (hThread == GetCurrentThread())
1011  else
1012  {
1013  SuspendThread(hThread);
1014  memset(&c, 0, sizeof(CONTEXT));
1015  c.ContextFlags = USED_CONTEXT_FLAGS;
1016  if (GetThreadContext(hThread, &c) == FALSE)
1017  {
1018  ResumeThread(hThread);
1019  return FALSE;
1020  }
1021  }
1022  }
1023  else
1024  c = *context;
1025 
1026  // init STACKFRAME for first call
1027  STACKFRAME64 s; // in/out stackframe
1028  memset(&s, 0, sizeof(s));
1029  DWORD imageType;
1030 #if defined(_M_IX86)
1031  // normally, call ImageNtHeader() and use machine info from PE header
1032  imageType = IMAGE_FILE_MACHINE_I386;
1033  s.AddrPC.Offset = c.Eip;
1034  s.AddrPC.Mode = AddrModeFlat;
1035  s.AddrFrame.Offset = c.Ebp;
1036  s.AddrFrame.Mode = AddrModeFlat;
1037  s.AddrStack.Offset = c.Esp;
1038  s.AddrStack.Mode = AddrModeFlat;
1039 #elif defined(_M_X64)
1040  imageType = IMAGE_FILE_MACHINE_AMD64;
1041  s.AddrPC.Offset = c.Rip;
1042  s.AddrPC.Mode = AddrModeFlat;
1043  s.AddrFrame.Offset = c.Rsp;
1044  s.AddrFrame.Mode = AddrModeFlat;
1045  s.AddrStack.Offset = c.Rsp;
1046  s.AddrStack.Mode = AddrModeFlat;
1047 #elif defined(_M_IA64)
1048  imageType = IMAGE_FILE_MACHINE_IA64;
1049  s.AddrPC.Offset = c.StIIP;
1050  s.AddrPC.Mode = AddrModeFlat;
1051  s.AddrFrame.Offset = c.IntSp;
1052  s.AddrFrame.Mode = AddrModeFlat;
1053  s.AddrBStore.Offset = c.RsBSP;
1054  s.AddrBStore.Mode = AddrModeFlat;
1055  s.AddrStack.Offset = c.IntSp;
1056  s.AddrStack.Mode = AddrModeFlat;
1057 #else
1058 #error "Platform not supported!"
1059 #endif
1060 
1061  pSym = (IMAGEHLP_SYMBOL64*) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
1062  if (!pSym)
1063  goto cleanup; // not enough memory...
1064  memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
1065  pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
1067 
1068  memset(&Line, 0, sizeof(Line));
1069  Line.SizeOfStruct = sizeof(Line);
1070 
1071  memset(&Module, 0, sizeof(Module));
1072  Module.SizeOfStruct = sizeof(Module);
1073 
1074  for (frameNum = 0; ; ++frameNum)
1075  {
1076  // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64())
1077  // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can
1078  // assume that either you are done, or that the stack is so hosed that the next
1079  // deeper frame could not be found.
1080  // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386!
1081  if (! m_sw->pSW(imageType, m_hProcess, hThread, &s, &c, myReadProcMem, m_sw->pSFTA, m_sw->pSGMB, NULL))
1082  {
1083  this->OnDbgHelpErr("StackWalk64", GetLastError(), s.AddrPC.Offset);
1084  break;
1085  }
1086 
1087  csEntry.offset = s.AddrPC.Offset;
1088  csEntry.name[0] = 0;
1089  csEntry.undName[0] = 0;
1090  csEntry.undFullName[0] = 0;
1091  csEntry.offsetFromSmybol = 0;
1092  csEntry.offsetFromLine = 0;
1093  csEntry.lineFileName[0] = 0;
1094  csEntry.lineNumber = 0;
1095  csEntry.loadedImageName[0] = 0;
1096  csEntry.moduleName[0] = 0;
1097  if (s.AddrPC.Offset == s.AddrReturn.Offset)
1098  {
1099  this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset);
1100  break;
1101  }
1102  if (s.AddrPC.Offset != 0)
1103  {
1104  // we seem to have a valid PC
1105  // show procedure info (SymGetSymFromAddr64())
1106  if (m_sw->pSGSFA(m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE)
1107  {
1108  strcpy_s(csEntry.name, pSym->Name);
1109  // UnDecorateSymbolName()
1112  }
1113  else
1114  this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset);
1115 
1116  // show line number info, NT5.0-method (SymGetLineFromAddr64())
1117  if (m_sw->pSGLFA != NULL)
1118  {
1119  // yes, we have SymGetLineFromAddr64()
1120  if (m_sw->pSGLFA(m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE)
1121  {
1122  csEntry.lineNumber = Line.LineNumber;
1123  strcpy_s(csEntry.lineFileName, Line.FileName);
1124  }
1125  else
1126  this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset);
1127  } // yes, we have SymGetLineFromAddr64()
1128 
1129  // show module info (SymGetModuleInfo64())
1130  if (m_sw->GetModuleInfo(m_hProcess, s.AddrPC.Offset, &Module) != FALSE)
1131  {
1132  // got module info OK
1133  switch (Module.SymType)
1134  {
1135  case SymNone:
1136  csEntry.symTypeString = "-nosymbols-";
1137  break;
1138  case SymCoff:
1139  csEntry.symTypeString = "COFF";
1140  break;
1141  case SymCv:
1142  csEntry.symTypeString = "CV";
1143  break;
1144  case SymPdb:
1145  csEntry.symTypeString = "PDB";
1146  break;
1147  case SymExport:
1148  csEntry.symTypeString = "-exported-";
1149  break;
1150  case SymDeferred:
1151  csEntry.symTypeString = "-deferred-";
1152  break;
1153  case SymSym:
1154  csEntry.symTypeString = "SYM";
1155  break;
1156 #if API_VERSION_NUMBER >= 9
1157  case SymDia:
1158  csEntry.symTypeString = "DIA";
1159  break;
1160 #endif
1161  case SymVirtual:
1162  csEntry.symTypeString = "Virtual";
1163  break;
1164  default:
1165  //_snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType );
1166  csEntry.symTypeString = NULL;
1167  break;
1168  }
1169 
1170  strcpy_s(csEntry.moduleName, Module.ModuleName);
1171  csEntry.baseOfImage = Module.BaseOfImage;
1172  strcpy_s(csEntry.loadedImageName, Module.LoadedImageName);
1173  } // got module info OK
1174  else
1175  this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset);
1176  } // we seem to have a valid PC
1177 
1179  if (frameNum == 0)
1180  et = firstEntry;
1181  this->OnCallstackEntry(et, csEntry);
1182 
1183  if (s.AddrReturn.Offset == 0)
1184  {
1185  this->OnCallstackEntry(lastEntry, csEntry);
1186  SetLastError(ERROR_SUCCESS);
1187  break;
1188  }
1189  } // for ( frameNum )
1190 
1191 cleanup:
1192  if (pSym)
1193  free(pSym);
1194 
1195  if (context == NULL)
1196  ResumeThread(hThread);
1197 
1198  return TRUE;
1199 }
1200 
1202  HANDLE hProcess,
1203  DWORD64 qwBaseAddress,
1204  PVOID lpBuffer,
1205  DWORD nSize,
1206  LPDWORD lpNumberOfBytesRead
1207 )
1208 {
1209  if (s_readMemoryFunction == NULL)
1210  {
1211  SIZE_T st;
1212  BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st);
1213  *lpNumberOfBytesRead = (DWORD) st;
1214  //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet);
1215  return bRet;
1216  }
1217  else
1218  return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData);
1219 }
1220 
1221 void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion)
1222 {
1223  CHAR buffer[STACKWALK_MAX_NAMELEN];
1224  if (fileVersion == 0)
1225  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName);
1226  else
1227  {
1228  DWORD v4 = (DWORD) fileVersion & 0xFFFF;
1229  DWORD v3 = (DWORD)(fileVersion >> 16) & 0xFFFF;
1230  DWORD v2 = (DWORD)(fileVersion >> 32) & 0xFFFF;
1231  DWORD v1 = (DWORD)(fileVersion >> 48) & 0xFFFF;
1232  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
1233  }
1234  OnOutput(buffer);
1235 }
1236 
1238 {
1239  CHAR buffer[STACKWALK_MAX_NAMELEN];
1240  if ((eType != lastEntry) && (entry.offset != 0))
1241  {
1242  if (entry.name[0] == 0)
1243  strcpy_s(entry.name, "(function-name not available)");
1244  if (entry.undName[0] != 0)
1245  strcpy_s(entry.name, entry.undName);
1246  if (entry.undFullName[0] != 0)
1247  strcpy_s(entry.name, entry.undFullName);
1248  if (entry.lineFileName[0] == 0)
1249  {
1250  strcpy_s(entry.lineFileName, "(filename not available)");
1251  if (entry.moduleName[0] == 0)
1252  strcpy_s(entry.moduleName, "(module-name not available)");
1253  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name);
1254  }
1255  else
1256  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s", entry.lineFileName, entry.lineNumber, entry.name);
1257  OnOutput(buffer);
1258  }
1259 }
1260 
1261 void StackWalker::OnDbgHelpErr(LPCSTR /*szFuncName*/, DWORD /*gle*/, DWORD64 /*addr*/)
1262 {
1263  //CHAR buffer[STACKWALK_MAX_NAMELEN];
1264  //_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)", szFuncName, gle, (LPVOID) addr);
1265  //OnOutput(buffer);
1266 }
1267 
1268 void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
1269 {
1270  CHAR buffer[STACKWALK_MAX_NAMELEN];
1271  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'", szSearchPath, symOptions, szUserName);
1272  OnOutput(buffer);
1273  // Also display the OS-version
1274 #if _MSC_VER <= 1200
1275  OSVERSIONINFOA ver;
1276  ZeroMemory(&ver, sizeof(OSVERSIONINFOA));
1277  ver.dwOSVersionInfoSize = sizeof(ver);
1278  if (GetVersionExA(&ver) != FALSE)
1279  {
1280  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)",
1281  ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
1282  ver.szCSDVersion);
1283  OnOutput(buffer);
1284  }
1285 #else
1286  OSVERSIONINFOEXA ver;
1287  ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA));
1288  ver.dwOSVersionInfoSize = sizeof(ver);
1289 #pragma warning(suppress: 4996)
1290  if (GetVersionExA((OSVERSIONINFOA*) &ver) != FALSE)
1291  {
1292  _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x",
1293  ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
1294  ver.szCSDVersion, ver.wSuiteMask, ver.wProductType);
1295  OnOutput(buffer);
1296  }
1297 #endif
1298 }
1299 
1301 {
1302  // OutputDebugStringA(buffer);
1303 }
1304 #endif
StackWalkerInternal::tSGO
DWORD(__stdcall * tSGO)(VOID)
Definition: stackwalker.cpp:463
_IMAGEHLP_MODULE64::SymType
SYM_TYPE SymType
Definition: stackwalker.cpp:140
StackWalker::CallstackEntry::baseOfImage
DWORD64 baseOfImage
Definition: stackwalker.h:176
StackWalker::OnDbgHelpErr
virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr)
Definition: stackwalker.cpp:1261
SIZE_T
unsigned long SIZE_T
Definition: stackwalker.h:92
StackWalker::myReadProcMem
static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
Definition: stackwalker.cpp:1201
_IMAGEHLP_MODULE64::CheckSum
DWORD CheckSum
Definition: stackwalker.cpp:138
s_readMemoryFunction_UserData
static LPVOID s_readMemoryFunction_UserData
Definition: stackwalker.cpp:975
StackWalker::OnCallstackEntry
virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry)
Definition: stackwalker.cpp:1237
StackWalkerInternal::tSC
BOOL(__stdcall * tSC)(IN HANDLE hProcess)
Definition: stackwalker.cpp:438
PIMAGEHLP_SYMBOL64
struct _IMAGEHLP_SYMBOL64 * PIMAGEHLP_SYMBOL64
_IMAGEHLP_LINE64::SizeOfStruct
DWORD SizeOfStruct
Definition: stackwalker.cpp:125
StackWalkerInternal::tagMODULEENTRY32::modBaseAddr
BYTE * modBaseAddr
Definition: stackwalker.cpp:518
StackWalkerInternal::IMAGEHLP_MODULE64_V2::LoadedImageName
CHAR LoadedImageName[256]
Definition: stackwalker.cpp:433
_tagSTACKFRAME64::AddrReturn
ADDRESS64 AddrReturn
Definition: stackwalker.cpp:187
_tagSTACKFRAME64::AddrPC
ADDRESS64 AddrPC
Definition: stackwalker.cpp:186
StackWalkerInternal::LPMODULEENTRY32
MODULEENTRY32 * LPMODULEENTRY32
Definition: stackwalker.cpp:525
PIMAGEHLP_MODULE64
struct _IMAGEHLP_MODULE64 * PIMAGEHLP_MODULE64
USED_CONTEXT_FLAGS
#define USED_CONTEXT_FLAGS
Definition: stackwalker.cpp:261
SYM_TYPE
SYM_TYPE
Definition: stackwalker.cpp:109
_KDHELP64::FramePointer
DWORD FramePointer
Definition: stackwalker.cpp:177
StackWalkerInternal::IMAGEHLP_MODULE64_V2
Definition: stackwalker.cpp:422
_KDHELP64::ThCallbackBStore
DWORD ThCallbackBStore
Definition: stackwalker.cpp:175
_snprintf_s
#define _snprintf_s
Definition: stackwalker.cpp:256
StackWalkerInternal::IMAGEHLP_MODULE64_V2::NumSyms
DWORD NumSyms
Definition: stackwalker.cpp:429
StackWalker::OptionsAll
@ OptionsAll
Definition: stackwalker.h:132
StackWalkerInternal::tSSO
DWORD(__stdcall * tSSO)(IN DWORD SymOptions)
Definition: stackwalker.cpp:481
s
XmlRpcServer s
StackWalkerInternal::pSSO
tSSO pSSO
Definition: stackwalker.cpp:482
UNDNAME_NAME_ONLY
#define UNDNAME_NAME_ONLY
Definition: stackwalker.cpp:244
StackWalkerInternal::LPMODULEINFO
struct StackWalkerInternal::_MODULEINFO * LPMODULEINFO
_tagSTACKFRAME64::KdHelp
KDHELP64 KdHelp
Definition: stackwalker.cpp:196
StackWalkerInternal::_MODULEINFO::EntryPoint
LPVOID EntryPoint
Definition: stackwalker.cpp:592
SymNone
@ SymNone
Definition: stackwalker.cpp:135
StackWalker::m_sw
StackWalkerInternal * m_sw
Definition: stackwalker.h:188
StackWalker::CallstackEntry::lineNumber
DWORD lineNumber
Definition: stackwalker.h:171
StackWalkerInternal::tagMODULEENTRY32::GlblcntUsage
DWORD GlblcntUsage
Definition: stackwalker.cpp:516
_IMAGEHLP_MODULE64
Definition: stackwalker.cpp:132
StackWalkerInternal::tagMODULEENTRY32::ProccntUsage
DWORD ProccntUsage
Definition: stackwalker.cpp:517
StackWalkerInternal::tagMODULEENTRY32::modBaseSize
DWORD modBaseSize
Definition: stackwalker.cpp:519
STACKFRAME64
struct _tagSTACKFRAME64 STACKFRAME64
_tagSTACKFRAME64::FuncTableEntry
PVOID FuncTableEntry
Definition: stackwalker.cpp:191
_IMAGEHLP_LINE64::Address
DWORD64 Address
Definition: stackwalker.cpp:129
StackWalkerInternal::tagMODULEENTRY32::th32ModuleID
DWORD th32ModuleID
Definition: stackwalker.cpp:514
AddrMode1616
@ AddrMode1616
Definition: stackwalker.cpp:158
StackWalkerInternal::pSLM
tSLM pSLM
Definition: stackwalker.cpp:478
StackWalkerInternal::tSLM
DWORD64(__stdcall * tSLM)(IN HANDLE hProcess, IN HANDLE hFile, IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll)
Definition: stackwalker.cpp:476
StackWalker::OnOutput
virtual void OnOutput(LPCSTR szText)
Definition: stackwalker.cpp:1300
StackWalker::CallstackEntry::offsetFromSmybol
DWORD64 offsetFromSmybol
Definition: stackwalker.h:169
_IMAGEHLP_LINE64::LineNumber
DWORD LineNumber
Definition: stackwalker.cpp:127
_IMAGEHLP_SYMBOL64::Size
DWORD Size
Definition: stackwalker.cpp:150
_IMAGEHLP_MODULE64::TimeDateStamp
DWORD TimeDateStamp
Definition: stackwalker.cpp:137
StackWalker::~StackWalker
virtual ~StackWalker()
Definition: stackwalker.cpp:841
StackWalker::CallstackEntry::undFullName
CHAR undFullName[STACKWALK_MAX_NAMELEN]
Definition: stackwalker.h:168
StackWalkerInternal::PMODULEENTRY32
MODULEENTRY32 * PMODULEENTRY32
Definition: stackwalker.cpp:524
StackWalkerInternal::IMAGEHLP_MODULE64_V2::BaseOfImage
DWORD64 BaseOfImage
Definition: stackwalker.cpp:425
StackWalkerInternal::LoadModules
BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId)
Definition: stackwalker.cpp:764
StackWalker::CallstackEntry::loadedImageName
CHAR loadedImageName[STACKWALK_MAX_NAMELEN]
Definition: stackwalker.h:177
_IMAGEHLP_SYMBOL64::MaxNameLength
DWORD MaxNameLength
Definition: stackwalker.cpp:152
IMAGEHLP_LINE64
struct _IMAGEHLP_LINE64 IMAGEHLP_LINE64
StackWalker::OnLoadModule
virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion)
Definition: stackwalker.cpp:1221
StackWalkerInternal::m_parent
StackWalker * m_parent
Definition: stackwalker.cpp:388
_KDHELP64::ThCallbackStack
DWORD ThCallbackStack
Definition: stackwalker.cpp:174
AddrModeFlat
@ AddrModeFlat
Definition: stackwalker.cpp:161
_tagSTACKFRAME64::AddrFrame
ADDRESS64 AddrFrame
Definition: stackwalker.cpp:188
StackWalker::CallstackEntry::offset
DWORD64 offset
Definition: stackwalker.h:165
StackWalkerInternal::tagMODULEENTRY32::hModule
HMODULE hModule
Definition: stackwalker.cpp:520
PKDHELP64
struct _KDHELP64 * PKDHELP64
StackWalkerInternal::IMAGEHLP_MODULE64_V2::ImageName
CHAR ImageName[256]
Definition: stackwalker.cpp:432
StackWalkerInternal::tSGMI
BOOL(__stdcall * tSGMI)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V2 *ModuleInfo)
Definition: stackwalker.cpp:455
_IMAGEHLP_MODULE64::BaseOfImage
DWORD64 BaseOfImage
Definition: stackwalker.cpp:135
_IMAGEHLP_SYMBOL64::Address
DWORD64 Address
Definition: stackwalker.cpp:149
_tagSTACKFRAME64::Reserved
DWORD64 Reserved[3]
Definition: stackwalker.cpp:195
strcat_s
#define strcat_s(dst, len, src)
Definition: stackwalker.cpp:255
StackWalker::CallstackEntry::moduleName
CHAR moduleName[STACKWALK_MAX_NAMELEN]
Definition: stackwalker.h:175
StackWalker::lastEntry
@ lastEntry
Definition: stackwalker.h:180
StackWalker::CallstackEntry::symTypeString
LPCSTR symTypeString
Definition: stackwalker.h:174
StackWalkerInternal::pSGLFA
tSGLFA pSGLFA
Definition: stackwalker.cpp:448
StackWalker::StackWalkerInternal
friend StackWalkerInternal
Definition: stackwalker.h:198
StackWalker::RetrieveFileVersion
@ RetrieveFileVersion
Definition: stackwalker.h:117
StackWalker::StackWalker
StackWalker()
Definition: stackwalker_linux.cpp:96
NumSymTypes
@ NumSymTypes
Definition: stackwalker.cpp:144
StackWalkerInternal
Definition: stackwalker.cpp:263
StackWalkerInternal::GetModuleListPSAPI
BOOL GetModuleListPSAPI(HANDLE hProcess)
Definition: stackwalker.cpp:595
StackWalker::m_szSymPath
LPSTR m_szSymPath
Definition: stackwalker.h:192
_KDHELP64::Thread
DWORD64 Thread
Definition: stackwalker.cpp:173
_tagSTACKFRAME64::AddrStack
ADDRESS64 AddrStack
Definition: stackwalker.cpp:189
StackWalkerInternal::GetModuleInfo
BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V2 *pModuleInfo)
Definition: stackwalker.cpp:774
StackWalkerInternal::tagMODULEENTRY32::th32ProcessID
DWORD th32ProcessID
Definition: stackwalker.cpp:515
ADDRESS_MODE
ADDRESS_MODE
Definition: stackwalker.cpp:156
StackWalker::ShowCallstack
void ShowCallstack()
Definition: stackwalker_linux.cpp:104
_IMAGEHLP_MODULE64::SizeOfStruct
DWORD SizeOfStruct
Definition: stackwalker.cpp:134
IMAGEHLP_MODULE64
struct _IMAGEHLP_MODULE64 IMAGEHLP_MODULE64
AddrModeReal
@ AddrModeReal
Definition: stackwalker.cpp:160
PDWORD64
unsigned __int64 * PDWORD64
Definition: stackwalker.h:88
StackWalkerInternal::_MODULEINFO
Definition: stackwalker.cpp:588
StackWalkerInternal::pSGSFA
tSGSFA pSGSFA
Definition: stackwalker.cpp:469
_tagSTACKFRAME64::Params
DWORD64 Params[4]
Definition: stackwalker.cpp:192
StackWalkerInternal::tagMODULEENTRY32::dwSize
DWORD dwSize
Definition: stackwalker.cpp:513
StackWalkerInternal::_MODULEINFO::SizeOfImage
DWORD SizeOfImage
Definition: stackwalker.cpp:591
PREAD_PROCESS_MEMORY_ROUTINE64
BOOL(__stdcall * PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
Definition: stackwalker.cpp:199
StackWalker::m_modulesLoaded
BOOL m_modulesLoaded
Definition: stackwalker.h:191
PIMAGEHLP_LINE64
struct _IMAGEHLP_LINE64 * PIMAGEHLP_LINE64
_tagADDRESS64
Definition: stackwalker.cpp:164
StackWalkerInternal::pSC
tSC pSC
Definition: stackwalker.cpp:439
PFUNCTION_TABLE_ACCESS_ROUTINE64
PVOID(__stdcall * PFUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE hProcess, DWORD64 AddrBase)
Definition: stackwalker.cpp:207
_IMAGEHLP_MODULE64::LoadedImageName
CHAR LoadedImageName[256]
Definition: stackwalker.cpp:143
StackWalker::OnSymInit
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
Definition: stackwalker.cpp:1268
_IMAGEHLP_LINE64::Key
PVOID Key
Definition: stackwalker.cpp:126
TH32CS_SNAPMODULE
#define TH32CS_SNAPMODULE
Definition: stackwalker.cpp:509
SYMOPT_FAIL_CRITICAL_ERRORS
#define SYMOPT_FAIL_CRITICAL_ERRORS
Definition: stackwalker.cpp:232
StackWalkerInternal::pUDSN
tUDSN pUDSN
Definition: stackwalker.cpp:500
DWORD64
unsigned __int64 DWORD64
Definition: stackwalker.h:88
StackWalker::nextEntry
@ nextEntry
Definition: stackwalker.h:180
SymCv
@ SymCv
Definition: stackwalker.cpp:137
StackWalker::m_hProcess
HANDLE m_hProcess
Definition: stackwalker.h:189
SymSym
@ SymSym
Definition: stackwalker.cpp:141
StackWalkerInternal::tSGLFA
BOOL(__stdcall * tSGLFA)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line)
Definition: stackwalker.cpp:446
SymDia
@ SymDia
Definition: stackwalker.cpp:142
SYMOPT_LOAD_LINES
#define SYMOPT_LOAD_LINES
Definition: stackwalker.cpp:227
_tagSTACKFRAME64::Far
BOOL Far
Definition: stackwalker.cpp:193
StackWalker::CallstackEntry::lineFileName
CHAR lineFileName[STACKWALK_MAX_NAMELEN]
Definition: stackwalker.h:172
StackWalkerInternal::m_hProcess
HANDLE m_hProcess
Definition: stackwalker.cpp:391
_IMAGEHLP_SYMBOL64::SizeOfStruct
DWORD SizeOfStruct
Definition: stackwalker.cpp:148
StackWalker::CallstackEntry
Container for each Callstack-Entry.
Definition: stackwalker.h:163
SymExport
@ SymExport
Definition: stackwalker.cpp:139
StackWalkerInternal::_MODULEINFO::lpBaseOfDll
LPVOID lpBaseOfDll
Definition: stackwalker.cpp:590
StackWalkerInternal::tagMODULEENTRY32
Definition: stackwalker.cpp:511
StackWalkerInternal::IMAGEHLP_MODULE64_V2::CheckSum
DWORD CheckSum
Definition: stackwalker.cpp:428
_IMAGEHLP_MODULE64::ImageSize
DWORD ImageSize
Definition: stackwalker.cpp:136
StackWalker::CallstackEntry::offsetFromLine
DWORD offsetFromLine
Definition: stackwalker.h:170
StackWalkerInternal::MODULEENTRY32
struct StackWalkerInternal::tagMODULEENTRY32 MODULEENTRY32
StackWalkerInternal::LoadModule
DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size)
Definition: stackwalker.cpp:684
stackwalker.h
_IMAGEHLP_MODULE64::ImageName
CHAR ImageName[256]
Definition: stackwalker.cpp:142
_tagADDRESS64::Mode
ADDRESS_MODE Mode
Definition: stackwalker.cpp:168
StackWalkerInternal::tUDSN
DWORD(__stdcall * tUDSN)(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags)
Definition: stackwalker.cpp:498
_IMAGEHLP_SYMBOL64
Definition: stackwalker.cpp:146
SymDeferred
@ SymDeferred
Definition: stackwalker.cpp:140
StackWalkerInternal::m_hDbhHelp
HMODULE m_hDbhHelp
Definition: stackwalker.cpp:390
StackWalkerInternal::~StackWalkerInternal
~StackWalkerInternal()
Definition: stackwalker.cpp:287
_IMAGEHLP_LINE64
Definition: stackwalker.cpp:123
StackWalkerInternal::tSFTA
PVOID(__stdcall * tSFTA)(HANDLE hProcess, DWORD64 AddrBase)
Definition: stackwalker.cpp:442
_IMAGEHLP_MODULE64::NumSyms
DWORD NumSyms
Definition: stackwalker.cpp:139
StackWalker::m_dwProcessId
DWORD m_dwProcessId
Definition: stackwalker.h:190
StackWalkerInternal::pSW
tSW pSW
Definition: stackwalker.cpp:495
StackWalkerInternal::pSGMI
tSGMI pSGMI
Definition: stackwalker.cpp:456
StackWalker::PReadProcessMemoryRoutine
BOOL(__stdcall * PReadProcessMemoryRoutine)(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead, LPVOID pUserData)
Definition: stackwalker.h:142
StackWalkerInternal::m_szSymPath
LPSTR m_szSymPath
Definition: stackwalker.cpp:392
_tagADDRESS64::Segment
WORD Segment
Definition: stackwalker.cpp:167
StackWalkerInternal::tSI
BOOL(__stdcall * tSI)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess)
Definition: stackwalker.cpp:472
StackWalker::firstEntry
@ firstEntry
Definition: stackwalker.h:180
StackWalkerInternal::pSFTA
tSFTA pSFTA
Definition: stackwalker.cpp:443
StackWalkerInternal::tagMODULEENTRY32::szExePath
char szExePath[MAX_PATH]
Definition: stackwalker.cpp:522
StackWalkerInternal::pSGSP
tSGSP pSGSP
Definition: stackwalker.cpp:503
BOOL
int BOOL
Definition: xstypedefs.h:141
StackWalkerInternal::IMAGEHLP_MODULE64_V2::SizeOfStruct
DWORD SizeOfStruct
Definition: stackwalker.cpp:424
SymVirtual
@ SymVirtual
Definition: stackwalker.cpp:143
_tcscat_s
#define _tcscat_s
Definition: stackwalker.cpp:257
StackWalkerInternal::tSW
BOOL(__stdcall * tSW)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress)
Definition: stackwalker.cpp:485
StackWalkerInternal::GetModuleListTH32
BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid)
Definition: stackwalker.cpp:528
StackWalker::SymBuildPath
@ SymBuildPath
Definition: stackwalker.h:123
strcpy_s
#define strcpy_s
Definition: stackwalker.cpp:254
_IMAGEHLP_LINE64::FileName
PCHAR FileName
Definition: stackwalker.cpp:128
KDHELP64
struct _KDHELP64 KDHELP64
StackWalker::STACKWALK_MAX_NAMELEN
@ STACKWALK_MAX_NAMELEN
Definition: stackwalker.h:160
StackWalker::CallstackEntry::undName
CHAR undName[STACKWALK_MAX_NAMELEN]
Definition: stackwalker.h:167
StackWalkerInternal::pSGMB
tSGMB pSGMB
Definition: stackwalker.cpp:452
StackWalker::CallstackEntryType
CallstackEntryType
Definition: stackwalker.h:180
StackWalkerInternal::pSI
tSI pSI
Definition: stackwalker.cpp:473
_tagSTACKFRAME64
Definition: stackwalker.cpp:184
_KDHELP64::SystemRangeStart
DWORD64 SystemRangeStart
Definition: stackwalker.cpp:180
GET_CURRENT_CONTEXT
#define GET_CURRENT_CONTEXT(c, contextFlags)
Definition: stackwalker.h:246
_tagSTACKFRAME64::AddrBStore
ADDRESS64 AddrBStore
Definition: stackwalker.cpp:190
_tagADDRESS64::Offset
DWORD64 Offset
Definition: stackwalker.cpp:166
StackWalkerInternal::Init
BOOL Init(LPCSTR szSymPath)
Definition: stackwalker.cpp:300
_IMAGEHLP_MODULE64::ModuleName
CHAR ModuleName[32]
Definition: stackwalker.cpp:141
StackWalkerInternal::MODULEINFO
struct StackWalkerInternal::_MODULEINFO MODULEINFO
StackWalkerInternal::tSGSFA
BOOL(__stdcall * tSGSFA)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol)
Definition: stackwalker.cpp:467
IMAGEHLP_SYMBOL64
struct _IMAGEHLP_SYMBOL64 IMAGEHLP_SYMBOL64
StackWalker
A class that can help with walking the stack for debugging purposes (Windows version)
Definition: stackwalker.h:98
INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES
Definition: stackwalker.cpp:249
AddrMode1632
@ AddrMode1632
Definition: stackwalker.cpp:159
_IMAGEHLP_SYMBOL64::Name
CHAR Name[1]
Definition: stackwalker.cpp:153
StackWalkerInternal::IMAGEHLP_MODULE64_V2::SymType
SYM_TYPE SymType
Definition: stackwalker.cpp:430
s_readMemoryFunction
static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction
Definition: stackwalker.cpp:974
StackWalkerInternal::tSGSP
BOOL(__stdcall * tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength)
Definition: stackwalker.cpp:502
_KDHELP64::NextCallback
DWORD NextCallback
Definition: stackwalker.cpp:176
PTRANSLATE_ADDRESS_ROUTINE64
DWORD64(__stdcall * PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, HANDLE hThread, LPADDRESS64 lpaddr)
Definition: stackwalker.cpp:217
SymPdb
@ SymPdb
Definition: stackwalker.cpp:138
UNDNAME_COMPLETE
#define UNDNAME_COMPLETE
Definition: stackwalker.cpp:243
_KDHELP64::Reserved
DWORD64 Reserved[8]
Definition: stackwalker.cpp:181
StackWalkerInternal::StackWalkerInternal
StackWalkerInternal(StackWalker *parent, HANDLE hProcess)
Definition: stackwalker.cpp:266
StackWalkerInternal::pSGO
tSGO pSGO
Definition: stackwalker.cpp:464
StackWalker::LoadModules
BOOL LoadModules()
Definition: stackwalker.cpp:851
StackWalkerInternal::tagMODULEENTRY32::szModule
char szModule[MAX_MODULE_NAME32+1]
Definition: stackwalker.cpp:521
StackWalker::m_options
int m_options
Definition: stackwalker.h:194
MAX_MODULE_NAME32
#define MAX_MODULE_NAME32
Definition: stackwalker.cpp:508
_tagSTACKFRAME64::Virtual
BOOL Virtual
Definition: stackwalker.cpp:194
StackWalker::CallstackEntry::name
CHAR name[STACKWALK_MAX_NAMELEN]
Definition: stackwalker.h:166
_KDHELP64::KiCallUserMode
DWORD64 KiCallUserMode
Definition: stackwalker.cpp:178
SymCoff
@ SymCoff
Definition: stackwalker.cpp:136
ADDRESS64
struct _tagADDRESS64 ADDRESS64
StackWalkerInternal::IMAGEHLP_MODULE64_V2::ModuleName
CHAR ModuleName[32]
Definition: stackwalker.cpp:431
StackWalkerInternal::tSGMB
DWORD64(__stdcall * tSGMB)(IN HANDLE hProcess, IN DWORD64 dwAddr)
Definition: stackwalker.cpp:451
_KDHELP64
Definition: stackwalker.cpp:171
PGET_MODULE_BASE_ROUTINE64
DWORD64(__stdcall * PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address)
Definition: stackwalker.cpp:212
StackWalkerInternal::IMAGEHLP_MODULE64_V2::TimeDateStamp
DWORD TimeDateStamp
Definition: stackwalker.cpp:427
LPSTACKFRAME64
struct _tagSTACKFRAME64 * LPSTACKFRAME64
LPCSTR
const typedef std::string & LPCSTR
Definition: stackwalker_linux.h:70
LPADDRESS64
struct _tagADDRESS64 * LPADDRESS64
StackWalkerInternal::IMAGEHLP_MODULE64_V2::ImageSize
DWORD ImageSize
Definition: stackwalker.cpp:426
_IMAGEHLP_SYMBOL64::Flags
DWORD Flags
Definition: stackwalker.cpp:151
_KDHELP64::KeUserCallbackDispatcher
DWORD64 KeUserCallbackDispatcher
Definition: stackwalker.cpp:179


xsens_mti_driver
Author(s):
autogenerated on Sun Sep 3 2023 02:43:20