OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
CBaseException Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/dev-utils/BaseException.h>

Inheritance diagram for CBaseException:
Collaboration diagram for CBaseException:

Public Member Functions

 CBaseException (HANDLE hProcess=GetCurrentProcess(), WORD wPID=GetCurrentProcessId(), LPCTSTR lpSymbolPath=NULL, PEXCEPTION_POINTERS pEp=NULL)
 ~CBaseException (void)
virtual void OutputString (LPCTSTR lpszFormat,...)
virtual void ShowLoadModules ()
virtual void ShowCallstack (HANDLE hThread=GetCurrentThread(), const CONTEXT *context=NULL)
virtual void ShowExceptionResoult (DWORD dwExceptionCode)
virtual BOOL GetLogicalAddress (PVOID addr, PTSTR szModule, DWORD len, DWORD &section, DWORD &offset)
virtual void ShowRegistorInformation (PCONTEXT pCtx)
virtual void ShowExceptionInformation ()
BOOL LoadSymbol ()
LPMODULE_INFO GetLoadModules ()
void GetModuleInformation (LPMODULE_INFO pmi)
void FreeModuleInformations (LPMODULE_INFO pmi)
LPSTACKINFO StackWalker (HANDLE hThread=GetCurrentThread(), const CONTEXT *context=NULL)
void FreeStackInformations (LPSTACKINFO psi)

Static Public Member Functions

static LONG WINAPI UnhandledExceptionFilter (PEXCEPTION_POINTERS pExceptionInfo)
static LONG WINAPI UnhandledExceptionFilter2 (PEXCEPTION_POINTERS pExceptionInfo)
static void STF (unsigned int ui, PEXCEPTION_POINTERS pEp)
static void set_log_folder (std::string log_folder)

Protected Member Functions

LPMODULE_INFO GetModulesTH32 ()
LPMODULE_INFO GetModulesPSAPI ()

Protected Attributes

PEXCEPTION_POINTERS m_pEp
boost::nowide::ofstream * output_file
HANDLE m_hProcess
WORD m_wPID
LPTSTR m_lpszSymbolPath
BOOL m_bSymbolLoaded

Detailed Description

Constructor & Destructor Documentation

◆ CBaseException()

CBaseException::CBaseException ( HANDLE hProcess = GetCurrentProcess(),
WORD wPID = GetCurrentProcessId(),
LPCTSTR lpSymbolPath = NULL,
PEXCEPTION_POINTERS pEp = NULL )
27 :
28 CStackWalker(hProcess, wPID, lpSymbolPath)
29{
30 if (NULL != pEp)
31 {
32 m_pEp = new EXCEPTION_POINTERS;
33 CopyMemory(m_pEp, pEp, sizeof(EXCEPTION_POINTERS));
34 }
35 output_file = new boost::nowide::ofstream();
36 std::time_t t = std::time(0);
37 std::tm* now_time = std::localtime(&t);
38 std::stringstream buf;
39
40 if (!g_log_folder.empty()) {
41 buf << std::put_time(now_time, "crash_%a_%b_%d_%H_%M_%S_") <<g_crash_log_count++ <<".log";
42 auto log_folder = (boost::filesystem::path(g_log_folder) / "log").make_preferred();
43 if (!boost::filesystem::exists(log_folder)) {
44 boost::filesystem::create_directory(log_folder);
45 }
46 auto crash_log_path = boost::filesystem::path(log_folder / buf.str()).make_preferred();
47 std::string log_filename = crash_log_path.string();
48 output_file->open(log_filename, std::ios::out | std::ios::app);
49
50 // Output app build info in crash log so we could look for the correct PDB files
51 OutputString(_T("%s\n\n"), _T(SLIC3R_APP_NAME " " SoftFever_VERSION " Build " GIT_COMMIT_HASH GIT_COMMIT_SUFFIX));
52 }
53}
static std::string g_log_folder
Definition BaseException.cpp:23
static std::atomic< int > g_crash_log_count
Definition BaseException.cpp:24
boost::nowide::ofstream * output_file
Definition BaseException.h:28
PEXCEPTION_POINTERS m_pEp
Definition BaseException.h:27
virtual void OutputString(LPCTSTR lpszFormat,...)
Definition BaseException.cpp:70
CStackWalker(HANDLE hProcess=GetCurrentProcess(), WORD wPID=GetCurrentProcessId(), LPCTSTR lpSymbolPath=NULL)
Definition StackWalker.cpp:11

References CStackWalker::CStackWalker(), g_crash_log_count, g_log_folder, m_pEp, output_file, and OutputString().

Referenced by STF(), UnhandledExceptionFilter(), and UnhandledExceptionFilter2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~CBaseException()

CBaseException::~CBaseException ( void )
56{
57 if (output_file) {
58 output_file->close();
59 delete output_file;
60 }
61}

References output_file.

Member Function Documentation

◆ FreeModuleInformations()

void CStackWalker::FreeModuleInformations ( LPMODULE_INFO pmi)
inherited
161{
162 LPMODULE_INFO head = pmi;
163 while (NULL != head)
164 {
165 pmi = pmi->pNext;
166 delete head;
167 head = pmi;
168 }
169}
struct _tag_MODULE_INFO * pNext
Definition StackWalker.h:206
struct _tag_MODULE_INFO * LPMODULE_INFO

References _tag_MODULE_INFO::pNext.

Referenced by CBaseException::ShowLoadModules().

Here is the caller graph for this function:

◆ FreeStackInformations()

void CStackWalker::FreeStackInformations ( LPSTACKINFO psi)
inherited
544{
545 LPSTACKINFO head = psi;
546 while (NULL != head)
547 {
548 psi = psi->pNext;
549 delete head;
550 head = psi;
551 }
552
553}
tagSTACKINFO * pNext
Definition StackWalker.h:217
struct tagSTACKINFO * LPSTACKINFO

References tagSTACKINFO::pNext.

Referenced by CBaseException::ShowCallstack().

Here is the caller graph for this function:

◆ GetLoadModules()

LPMODULE_INFO CStackWalker::GetLoadModules ( )
inherited
150{
152 if (NULL == pHead)
153 {
154 pHead = GetModulesPSAPI();
155 }
156
157 return pHead;
158}
LPMODULE_INFO GetModulesPSAPI()
Definition StackWalker.cpp:256
LPMODULE_INFO GetModulesTH32()
Definition StackWalker.cpp:171

References GetModulesPSAPI(), and GetModulesTH32().

Referenced by CBaseException::ShowLoadModules().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetLogicalAddress()

BOOL CBaseException::GetLogicalAddress ( PVOID addr,
PTSTR szModule,
DWORD len,
DWORD & section,
DWORD & offset )
virtual
307{
308 MEMORY_BASIC_INFORMATION mbi;
309
310 if ( !VirtualQuery( addr, &mbi, sizeof(mbi) ) )
311 return FALSE;
312
313 DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase;
314
315 if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
316 return FALSE;
317
318 if (!hMod)
319 return FALSE;
320
321 PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
322 PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
323 PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
324
325 DWORD_PTR rva = (DWORD_PTR)addr - hMod;
326
327 //���㵱ǰ��ַ�ڵڼ�����
328 for (unsigned i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++ )
329 {
330 DWORD sectionStart = pSection->VirtualAddress;
331 DWORD sectionEnd = sectionStart + std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
332
333 if ( (rva >= sectionStart) && (rva <= sectionEnd) )
334 {
335 section = i+1;
336 offset = rva - sectionStart;
337 return TRUE;
338 }
339 }
340
341 return FALSE; // Should never get here!
342}
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582

Referenced by ShowCallstack(), and ShowExceptionInformation().

Here is the caller graph for this function:

◆ GetModuleInformation()

void CStackWalker::GetModuleInformation ( LPMODULE_INFO pmi)
inherited
358{
359 //USES_CONVERSION;
360 IMAGEHLP_MODULE64 im = {0};
361 im.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
362
363 VS_FIXEDFILEINFO* pvfi = NULL;
364 DWORD dwHandle = 0;
365 DWORD dwInfoSize = 0;
366 dwInfoSize = GetFileVersionInfoSize(pmi->szModulePath, &dwHandle);
367
368 if (dwInfoSize > 0)
369 {
370 byte *lpData = new byte[dwInfoSize];
371 ZeroMemory(lpData, dwInfoSize * sizeof(byte));
372
373 if (GetFileVersionInfo(pmi->szModulePath, dwHandle, dwInfoSize, lpData) > 0 )
374 {
375 TCHAR szBlock[] = _T("\\");
376 UINT len;
377 if (VerQueryValue(lpData, szBlock, (LPVOID*)&pvfi, &len))
378 {
379 WORD v1 = HIWORD(pvfi->dwFileVersionMS);
380 WORD v2 = LOWORD(pvfi->dwFileVersionMS);
381 WORD v3 = HIWORD(pvfi->dwFileVersionLS);
382 WORD v4 = LOWORD(pvfi->dwFileVersionLS);
383 _stprintf_s(pmi->szVersion, MAX_VERSION_LENGTH, _T("%d.%d.%d.%d"), v1, v2, v3, v4);
384 }
385 }
386
387 delete[] lpData;
388 }
389
390 SymGetModuleInfo64(m_hProcess, pmi->ModuleAddress, &im);
391 StringCchCopy(pmi->szSymbolPath, MAX_PATH, textconv_helper::A2T_(im.LoadedPdbName));
392}
DWORD64 ModuleAddress
Definition StackWalker.h:200
#define MAX_VERSION_LENGTH
Definition StackWalker.h:163
TCHAR szVersion[MAX_VERSION_LENGTH]
Definition StackWalker.h:205
TCHAR szSymbolPath[MAX_PATH]
Definition StackWalker.h:204
TCHAR szModulePath[MAX_PATH]
Definition StackWalker.h:203
HANDLE m_hProcess
Definition StackWalker.h:239
CA2A_ A2T_
Definition StackWalker.h:33

References m_hProcess, MAX_VERSION_LENGTH, _tag_MODULE_INFO::ModuleAddress, _tag_MODULE_INFO::szModulePath, _tag_MODULE_INFO::szSymbolPath, and _tag_MODULE_INFO::szVersion.

Referenced by GetModulesPSAPI(), and GetModulesTH32().

Here is the caller graph for this function:

◆ GetModulesPSAPI()

LPMODULE_INFO CStackWalker::GetModulesPSAPI ( )
protectedinherited
257{
258 LPMODULE_INFO pHead = NULL;
259 LPMODULE_INFO pTail = pHead;
260 typedef BOOL(WINAPI *pfnEnumProcessModules)(HANDLE hProcess, HMODULE * lphModule, DWORD cb,LPDWORD lpcbNeeded);
261 typedef DWORD(WINAPI *pfnGetModuleFileNameEx)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
262 typedef DWORD(WINAPI *pfnGetModuleBaseName)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
263 typedef BOOL(WINAPI *pfnGetModuleInformation)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize);
264
265 HINSTANCE hPsapi;
266 pfnEnumProcessModules EnumProcessModules = NULL;
267 pfnGetModuleFileNameEx GetModuleFileNameEx = NULL;
268 pfnGetModuleBaseName GetModuleBaseName = NULL;
269 pfnGetModuleInformation GetModuleInformation = NULL;
270
271 DWORD i;
272 //ModuleEntry e;
273 DWORD cbNeeded;
274 MODULEINFO mi;
275 HMODULE* hMods = NULL;
276 TCHAR szModuleName[MAX_MODULE_NAME32 + 1] = _T("");
277 TCHAR szModulePath[MAX_PATH] = _T("");
278
279 hPsapi = LoadLibrary(_T("psapi.dll"));
280 if (hPsapi == NULL)
281 {
282 return pHead;
283 }
284
285 EnumProcessModules = (pfnEnumProcessModules)GetProcAddress(hPsapi, "EnumProcessModules");
286#ifdef UNICODE
287 GetModuleFileNameEx = (pfnGetModuleFileNameEx)GetProcAddress(hPsapi, "GetModuleFileNameExW");
288 GetModuleBaseName = (pfnGetModuleBaseName)GetProcAddress(hPsapi, "GetModuleBaseNameW");
289#else
290 GetModuleFileNameEx = (pfnGetModuleFileNameEx)GetProcAddress(hPsapi, "GetModuleFileNameExA");
291 GetModuleBaseName = (pfnGetModuleBaseName)GetProcAddress(hPsapi, "GetModuleBaseNameA");
292#endif
293 GetModuleInformation = (pfnGetModuleInformation)GetProcAddress(hPsapi, "GetModuleInformation");
294 if ((EnumProcessModules == NULL) || (GetModuleFileNameEx == NULL) || (GetModuleBaseName == NULL) || (GetModuleInformation == NULL))
295 {
296 FreeLibrary(hPsapi);
297 return pHead;
298 }
299
300 EnumProcessModules(m_hProcess, hMods, 0, &cbNeeded);
301 hMods = new HMODULE[cbNeeded / sizeof(HMODULE)];
302 ASSERT(NULL != hMods);
303 ZeroMemory(hMods, cbNeeded);
304
305 if (!EnumProcessModules(m_hProcess, hMods, cbNeeded, &cbNeeded))
306 {
307 goto cleanup;
308 }
309
310 for (i = 0; i < cbNeeded / sizeof(HMODULE); i++)
311 {
312 GetModuleInformation(m_hProcess, hMods[i], &mi, sizeof(mi));
313 GetModuleFileNameEx(m_hProcess, hMods[i], szModulePath, MAX_PATH);
314 GetModuleBaseName(m_hProcess, hMods[i], szModuleName, MAX_MODULE_NAME32);
315 LPMODULE_INFO pmi = new MODULE_INFO;
316 ZeroMemory(pmi, sizeof(MODULE_INFO));
317 pmi->dwModSize = mi.SizeOfImage;
318 pmi->ModuleAddress = (DWORD64)mi.lpBaseOfDll;
319 StringCchCopy(pmi->szModuleName, MAX_MODULE_NAME32, szModuleName);
320 StringCchCopy(pmi->szModulePath, MAX_PATH, szModulePath);
321 this->GetModuleInformation(pmi);
322 if (pHead == NULL)
323 {
324 pHead = pmi;
325 pTail = pHead;
326 }else
327 {
328 pTail->pNext = pmi;
329 pTail = pmi;
330 }
331 }
332
333cleanup:
334 if (hPsapi != NULL)
335 {
336 FreeLibrary(hPsapi);
337 }
338 if (hMods != NULL)
339 {
340 delete[] hMods;
341 }
342
343 return pHead;
344}
struct _MODULEINFO MODULEINFO
struct _tag_MODULE_INFO MODULE_INFO
DWORD SizeOfImage
Definition StackWalker.h:191
TCHAR szModuleName[MAX_MODULE_NAME32+1]
Definition StackWalker.h:202
LPVOID lpBaseOfDll
Definition StackWalker.h:190
DWORD dwModSize
Definition StackWalker.h:201
#define ASSERT(judge)
Definition StackWalker.h:166
struct _MODULEINFO * LPMODULEINFO
#define MAX_MODULE_NAME32
Definition StackWalker.h:161
void GetModuleInformation(LPMODULE_INFO pmi)
Definition StackWalker.cpp:357

References ASSERT, _tag_MODULE_INFO::dwModSize, GetModuleInformation(), _MODULEINFO::lpBaseOfDll, m_hProcess, MAX_MODULE_NAME32, _tag_MODULE_INFO::ModuleAddress, _tag_MODULE_INFO::pNext, _MODULEINFO::SizeOfImage, _tag_MODULE_INFO::szModuleName, and _tag_MODULE_INFO::szModulePath.

Referenced by GetLoadModules().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetModulesTH32()

LPMODULE_INFO CStackWalker::GetModulesTH32 ( )
protectedinherited
172{
173 //这里为了防止加载Toolhelp.dll 影响最终结果,所以采用动态加载的方式
174 LPMODULE_INFO pHead = NULL;
175 LPMODULE_INFO pTail = pHead;
176
177 typedef HANDLE (WINAPI *pfnCreateToolhelp32Snapshot)(DWORD dwFlags, DWORD th32ProcessID);
178 typedef BOOL (WINAPI *pfnModule32First)(HANDLE hSnapshot, LPMODULEENTRY32 lpme );
179 typedef BOOL (WINAPI *pfnModule32Next)(HANDLE hSnapshot, LPMODULEENTRY32 lpme );
180
181 const TCHAR* dllname[] = {_T("kernel32.dll"), _T("tlhelp32.dll")};
182 HINSTANCE hToolhelp = NULL;
183
184 pfnCreateToolhelp32Snapshot CreateToolhelp32Snapshot = NULL;
185 pfnModule32First Module32First = NULL;
186 pfnModule32Next Module32Next = NULL;
187
188 HANDLE hSnap;
189 MODULEENTRY32 me;
190 me.dwSize = sizeof(me);
191 BOOL keepGoing;
192 size_t i;
193
194 for (i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
195 {
196 hToolhelp = LoadLibrary(dllname[i]);
197 if (hToolhelp == NULL)
198 continue;
199 CreateToolhelp32Snapshot = (pfnCreateToolhelp32Snapshot)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
200#ifdef UNICODE
201 Module32First = (pfnModule32First)GetProcAddress(hToolhelp, "Module32FirstW");
202 Module32Next = (pfnModule32Next)GetProcAddress(hToolhelp, "Module32NextW");
203#else
204 Module32First = (pfnModule32First)GetProcAddress(hToolhelp, "Module32FirstA");
205 Module32Next = (pfnModule32Next)GetProcAddress(hToolhelp, "Module32NextA");
206#endif
207
208 if ((CreateToolhelp32Snapshot != NULL) && (Module32First != NULL) && (Module32Next != NULL))
209 break;
210
211 FreeLibrary(hToolhelp);
212 hToolhelp = NULL;
213 }
214
215 if (hToolhelp == NULL)
216 return pHead;
217
218 hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_wPID);
219
220 if (hSnap == INVALID_HANDLE_VALUE)
221 {
222 FreeLibrary(hToolhelp);
223 return pHead;
224 }
225
226 keepGoing = Module32First(hSnap, &me);
227
228 while (keepGoing)
229 {
230 LPMODULE_INFO pmi = new MODULE_INFO;
231 ZeroMemory(pmi, sizeof(MODULE_INFO));
232
233 pmi->dwModSize = me.modBaseSize;
234 pmi->ModuleAddress = (DWORD64)me.modBaseAddr;
235 StringCchCopy(pmi->szModuleName, MAX_MODULE_NAME32, me.szModule);
236 StringCchCopy(pmi->szModulePath, MAX_PATH, me.szExePath);
238 if (pHead == NULL)
239 {
240 pHead = pmi;
241 pTail = pHead;
242 }else
243 {
244 pTail->pNext = pmi;
245 pTail = pmi;
246 }
247
248 keepGoing = Module32Next(hSnap, &me);
249 }
250
251 CloseHandle(hSnap);
252 FreeLibrary(hToolhelp);
253 return pHead;
254}
BYTE * modBaseAddr
Definition StackWalker.h:181
MODULEENTRY32 * LPMODULEENTRY32
Definition StackWalker.h:196
TCHAR szExePath[MAX_PATH]
Definition StackWalker.h:185
DWORD dwSize
Definition StackWalker.h:176
#define TH32CS_SNAPMODULE
Definition StackWalker.h:162
TCHAR szModule[MAX_MODULE_NAME32+1]
Definition StackWalker.h:184
DWORD modBaseSize
Definition StackWalker.h:182
struct tagMODULEENTRY32 MODULEENTRY32
WORD m_wPID
Definition StackWalker.h:240

References _tag_MODULE_INFO::dwModSize, tagMODULEENTRY32::dwSize, GetModuleInformation(), m_wPID, MAX_MODULE_NAME32, tagMODULEENTRY32::modBaseAddr, tagMODULEENTRY32::modBaseSize, _tag_MODULE_INFO::ModuleAddress, _tag_MODULE_INFO::pNext, tagMODULEENTRY32::szExePath, tagMODULEENTRY32::szModule, _tag_MODULE_INFO::szModuleName, _tag_MODULE_INFO::szModulePath, and TH32CS_SNAPMODULE.

Referenced by GetLoadModules().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadSymbol()

BOOL CStackWalker::LoadSymbol ( )
inherited
42{
43 //USES_CONVERSION;
44 //只加载一次
46 {
47 return m_bSymbolLoaded;
48 }
49
50 if (NULL != m_lpszSymbolPath)
51 {
52
54 return m_bSymbolLoaded;
55 }
56
57 //添加当前程序路径
58 TCHAR szSymbolPath[MAX_SYMBOL_PATH] = _T("");
59 StringCchCopy(szSymbolPath, MAX_SYMBOL_PATH, _T(".;"));
60
61 //添加程序所在目录
62 TCHAR szTemp[MAX_PATH] = _T("");
63 if (GetCurrentDirectory(MAX_PATH, szTemp) > 0)
64 {
65 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
66 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
67 }
68
69 //添加程序主模块所在路径
70 ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
71 if (GetModuleFileName(NULL, szTemp, MAX_PATH) > 0)
72 {
73 size_t sLength = 0;
74 StringCchLength(szTemp, MAX_PATH, &sLength);
75 for (int i = sLength; i >= 0; i--)
76 {
77 if (szTemp[i] == _T('\\') || szTemp[i] == _T('/') || szTemp[i] == _T(':'))
78 {
79 szTemp[i] = _T('\0');
80 break;
81 }
82 }
83 }
84
85 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
86 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
87
88 ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
89 if (GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), szTemp, MAX_PATH) > 0)
90 {
91 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
92 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
93 }
94
95 ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
96 if (GetEnvironmentVariable(_T("_NT_ALTERNATE_SYMBOL_PATH"), szTemp, MAX_PATH) > 0)
97 {
98 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
99 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
100 }
101
102 ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
103 if (GetEnvironmentVariable(_T("SYSTEMROOT"), szTemp, MAX_PATH) > 0)
104 {
105 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
106 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
107 // also add the "system32"-directory:
108 StringCchCat(szTemp, MAX_PATH, _T("\\system32"));
109 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
110 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
111 }
112
113 ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
114 if (GetEnvironmentVariable(_T("SYSTEMDRIVE"), szTemp, MAX_PATH) > 0)
115 {
116 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("SRV*"));
117 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
118 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("\\websymbols"));
119 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("*http://msdl.microsoft.com/download/symbols;"));
120 }
121 else
122 {
123 StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"));
124 }
125
126 size_t sLength = 0;
127 StringCchLength(szSymbolPath, MAX_SYMBOL_PATH, &sLength);
128 if (sLength > 0)
129 {
130 m_lpszSymbolPath = new TCHAR[sLength + 1];
131 ZeroMemory(m_lpszSymbolPath, sizeof(TCHAR) * (sLength + 1));
132 StringCchCopy(m_lpszSymbolPath, sLength, szSymbolPath);
133 }
134
135 if (NULL != m_lpszSymbolPath)
136 {
137 m_bSymbolLoaded = SymInitialize(m_hProcess, textconv_helper::T2A_(m_lpszSymbolPath), TRUE); //这里设置为TRUE,让它在初始化符号表的同时加载符号表
138 }
139
140 DWORD symOptions = SymGetOptions();
141 symOptions |= SYMOPT_LOAD_LINES;
142 symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
143 symOptions |= SYMOPT_DEBUG;
144 SymSetOptions(symOptions);
145
146 return m_bSymbolLoaded;
147}
#define MAX_SYMBOL_PATH
Definition StackWalker.h:160
LPTSTR m_lpszSymbolPath
Definition StackWalker.h:241
BOOL m_bSymbolLoaded
Definition StackWalker.h:242
CA2A_ T2A_
Definition StackWalker.h:34

References m_bSymbolLoaded, m_hProcess, m_lpszSymbolPath, and MAX_SYMBOL_PATH.

Referenced by CBaseException::ShowLoadModules(), and StackWalker().

Here is the caller graph for this function:

◆ OutputString()

void CBaseException::OutputString ( LPCTSTR lpszFormat,
... )
virtual

Reimplemented from CStackWalker.

71{
72 TCHAR szBuf[2048] = _T("");
73 va_list args;
74 va_start(args, lpszFormat);
75 _vsntprintf_s(szBuf, 2048, lpszFormat, args);
76 va_end(args);
77
78 //WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), szBuf, _tcslen(szBuf), NULL, NULL);
79
80 //output it to the current directory of binary
81 std::string output_str = static_cast<const char*>(textconv_helper::T2A_(szBuf));
82 *output_file << output_str;
83 output_file->flush();
84}

References output_file.

Referenced by CBaseException(), ShowCallstack(), ShowExceptionInformation(), ShowExceptionResoult(), ShowLoadModules(), and ShowRegistorInformation().

Here is the caller graph for this function:

◆ set_log_folder()

void CBaseException::set_log_folder ( std::string log_folder)
static
66{
67 g_log_folder = log_folder;
68}

References g_log_folder.

Referenced by Slic3r::GUI::GUI_App::on_init_inner().

Here is the caller graph for this function:

◆ ShowCallstack()

void CBaseException::ShowCallstack ( HANDLE hThread = GetCurrentThread(),
const CONTEXT * context = NULL )
virtual
107{
108 OutputString(_T("Show CallStack:\n"));
109 LPSTACKINFO phead = StackWalker(hThread, context);
110
111 // Show RVA of each call stack, so we can locate the symbol using pdb file
112 // To show the symbol, load the <szFaultingModule> in WinDBG with pdb file, then type the following commands:
113 // > lm which gives you the start address of each module, as well as module names
114 // > !dh <module name> list all module headers. Find the <virtual address> of the section given by
115 // the <section> output in the crash log
116 // > ln <module start address> + <section virtual address> + <offset> reveals the debug symbol
117 OutputString(_T("\nLogical Address:\n"));
118 TCHAR szFaultingModule[MAX_PATH];
119 DWORD section, offset;
120 for (LPSTACKINFO ps = phead; ps != nullptr; ps = ps->pNext) {
121 if (GetLogicalAddress((PVOID) ps->szFncAddr, szFaultingModule, sizeof(szFaultingModule), section, offset)) {
122 OutputString(_T("0x%X 0x%X:0x%X %s\n"), ps->szFncAddr, section, offset, szFaultingModule);
123 } else {
124 OutputString(_T("0x%X Unknown\n"), ps->szFncAddr);
125 }
126 }
127
129}
virtual BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len, DWORD &section, DWORD &offset)
Definition BaseException.cpp:305
void FreeStackInformations(LPSTACKINFO psi)
Definition StackWalker.cpp:543
LPSTACKINFO StackWalker(HANDLE hThread=GetCurrentThread(), const CONTEXT *context=NULL)
Definition StackWalker.cpp:394

References CStackWalker::FreeStackInformations(), GetLogicalAddress(), OutputString(), tagSTACKINFO::pNext, and CStackWalker::StackWalker().

Referenced by ShowExceptionInformation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowExceptionInformation()

void CBaseException::ShowExceptionInformation ( )
virtual
387{
388 OutputString(_T("Exceptions:\r\n"));
389 ShowExceptionResoult(m_pEp->ExceptionRecord->ExceptionCode);
390
391 OutputString(_T("Exception Flag :0x%x "), m_pEp->ExceptionRecord->ExceptionFlags);
392 OutputString(_T("NumberParameters :%ld \n"), m_pEp->ExceptionRecord->NumberParameters);
393 for (int i = 0; i < m_pEp->ExceptionRecord->NumberParameters; i++)
394 {
395 OutputString(_T("Param %d :0x%x \n"), i, m_pEp->ExceptionRecord->ExceptionInformation[i]);
396 }
397 OutputString(_T("Context :%p \n"), m_pEp->ContextRecord);
398#if defined(_M_ARM64)
399 OutputString(_T("ContextFlag : 0x%x, Cpsr: 0x%x \n"), m_pEp->ContextRecord->ContextFlags, m_pEp->ContextRecord->Cpsr);
400#else
401 OutputString(_T("ContextFlag : 0x%x, EFlags: 0x%x \n"), m_pEp->ContextRecord->ContextFlags, m_pEp->ContextRecord->EFlags);
402#endif
403
404 TCHAR szFaultingModule[MAX_PATH];
405 DWORD section, offset;
406 GetLogicalAddress(m_pEp->ExceptionRecord->ExceptionAddress, szFaultingModule, sizeof(szFaultingModule), section, offset );
407 OutputString( _T("Fault address: 0x%X 0x%X:0x%X %s\r\n"), m_pEp->ExceptionRecord->ExceptionAddress, section, offset, szFaultingModule );
408
409 ShowRegistorInformation(m_pEp->ContextRecord);
410
411 ShowCallstack(GetCurrentThread(), m_pEp->ContextRecord);
412}
virtual void ShowExceptionResoult(DWORD dwExceptionCode)
Definition BaseException.cpp:131
virtual void ShowRegistorInformation(PCONTEXT pCtx)
Definition BaseException.cpp:344
virtual void ShowCallstack(HANDLE hThread=GetCurrentThread(), const CONTEXT *context=NULL)
Definition BaseException.cpp:106

References GetLogicalAddress(), m_pEp, OutputString(), ShowCallstack(), ShowExceptionResoult(), and ShowRegistorInformation().

Referenced by UnhandledExceptionFilter(), and UnhandledExceptionFilter2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowExceptionResoult()

void CBaseException::ShowExceptionResoult ( DWORD dwExceptionCode)
virtual
132{
133 OutputString(_T("Exception Code :%08x "), dwExceptionCode);
134// BBS: to be checked
135#if 1
136 switch (dwExceptionCode)
137 {
138 case EXCEPTION_ACCESS_VIOLATION:
139 {
140 //OutputString(_T("ACCESS_VIOLATION(%s)\r\n"), _T("��д�Ƿ��ڴ�"));
141 OutputString(_T("ACCESS_VIOLATION\r\n"));
142 }
143 return ;
144 case EXCEPTION_DATATYPE_MISALIGNMENT:
145 {
146 //OutputString(_T("DATATYPE_MISALIGNMENT(%s)\r\n"), _T("�߳���ͼ�ڲ�֧�ֶ����Ӳ���϶�дδ���������"));
147 OutputString(_T("DATATYPE_MISALIGNMENT\r\n"));
148 }
149 return ;
150 case EXCEPTION_BREAKPOINT:
151 {
152 //OutputString(_T("BREAKPOINT(%s)\r\n"), _T("����һ���ϵ�"));
153 OutputString(_T("BREAKPOINT\r\n"));
154 }
155 return ;
156 case EXCEPTION_SINGLE_STEP:
157 {
158 //OutputString(_T("SINGLE_STEP(%s)\r\n"), _T("����")); //һ���Ƿ����ڵ����¼���
159 OutputString(_T("SINGLE_STEP\r\n"));
160 }
161 return ;
162 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
163 {
164 //OutputString(_T("ARRAY_BOUNDS_EXCEEDED(%s)\r\n"), _T("�������Խ��"));
165 OutputString(_T("ARRAY_BOUNDS_EXCEEDED\r\n"));
166 }
167 return ;
168 case EXCEPTION_FLT_DENORMAL_OPERAND:
169 {
170 //OutputString(_T("FLT_DENORMAL_OPERAND(%s)\r\n"), _T("���������һ�������������棬�����ĸ������޷���ʾ")); //������������
171 OutputString(_T("FLT_DENORMAL_OPERAND\r\n"));
172 }
173 return ;
174 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
175 {
176 //OutputString(_T("FLT_DIVIDE_BY_ZERO(%s)\r\n"), _T("��������0����"));
177 OutputString(_T("FLT_DIVIDE_BY_ZERO\r\n"));
178 }
179 return ;
180 case EXCEPTION_FLT_INEXACT_RESULT:
181 {
182 //OutputString(_T("FLT_INEXACT_RESULT(%s)\r\n"), _T("�����������Ľ���޷���ʾ")); //�޷���ʾһ��������̫С��������������ʾ�ķ�Χ, ����֮������Ľ���쳣
183 OutputString(_T("FLT_INEXACT_RESULT\r\n"));
184 }
185 return ;
186 case EXCEPTION_FLT_INVALID_OPERATION:
187 {
188 //OutputString(_T("FLT_INVALID_OPERATION(%s)\r\n"), _T("�����������쳣"));
189 OutputString(_T("FLT_INVALID_OPERATION\r\n"));
190 }
191 return ;
192 case EXCEPTION_FLT_OVERFLOW:
193 {
194 //OutputString(_T("FLT_OVERFLOW(%s)\r\n"), _T("���������ָ����������Ӧ���͵����ֵ"));
195 OutputString(_T("FLT_OVERFLOW\r\n"));
196 }
197 return ;
198 case EXCEPTION_FLT_STACK_CHECK:
199 {
200 //OutputString(_T("STACK_CHECK(%s)\r\n"), _T("ջԽ�����ջ�������"));
201 OutputString(_T("STACK_CHECK\r\n"));
202 }
203 return ;
204 case EXCEPTION_INT_DIVIDE_BY_ZERO:
205 {
206 //OutputString(_T("INT_DIVIDE_BY_ZERO(%s)\r\n"), _T("������0�쳣"));
207 OutputString(_T("INT_DIVIDE_BY_ZERO\r\n"));
208 }
209 return ;
210 case EXCEPTION_INVALID_HANDLE:
211 {
212 //OutputString(_T("INVALID_HANDLE(%s)\r\n"), _T("�����Ч"));
213 OutputString(_T("INVALID_HANDLE\r\n"));
214 }
215 return ;
216 case EXCEPTION_PRIV_INSTRUCTION:
217 {
218 //OutputString(_T("PRIV_INSTRUCTION(%s)\r\n"), _T("�߳���ͼִ�е�ǰ����ģʽ��֧�ֵ�ָ��"));
219 OutputString(_T("PRIV_INSTRUCTION\r\n"));
220 }
221 return ;
222 case EXCEPTION_IN_PAGE_ERROR:
223 {
224 //OutputString(_T("IN_PAGE_ERROR(%s)\r\n"), _T("�߳���ͼ����δ���ص������ڴ�ҳ���߲��ܼ��ص������ڴ�ҳ"));
225 OutputString(_T("IN_PAGE_ERROR\r\n"));
226 }
227 return ;
228 case EXCEPTION_ILLEGAL_INSTRUCTION:
229 {
230 //OutputString(_T("ILLEGAL_INSTRUCTION(%s)\r\n"), _T("�߳���ͼִ����Чָ��"));
231 OutputString(_T("ILLEGAL_INSTRUCTION\r\n"));
232 }
233 return ;
234 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
235 {
236 //OutputString(_T("NONCONTINUABLE_EXCEPTION(%s)\r\n"), _T("�߳���ͼ��һ�����ɼ���ִ�е��쳣���������ִ��"));
237 OutputString(_T("NONCONTINUABLE_EXCEPTION\r\n"));
238 }
239 return ;
240 case EXCEPTION_STACK_OVERFLOW:
241 {
242 //OutputString(_T("STACK_OVERFLOW(%s)\r\n"), _T("ջ���"));
243 OutputString(_T("STACK_OVERFLOW\r\n"));
244 }
245 return ;
246 case EXCEPTION_INVALID_DISPOSITION:
247 {
248 //OutputString(_T("INVALID_DISPOSITION(%s)\r\n"), _T("�쳣���������쳣������������һ����Ч����")); //ʹ�ø߼����Ա�д�ij�����Զ������������쳣
249 OutputString(_T("INVALID_DISPOSITION\r\n"));
250 }
251 return ;
252 case EXCEPTION_FLT_UNDERFLOW:
253 {
254 //OutputString(_T("FLT_UNDERFLOW(%s)\r\n"), _T("������������ָ��С����Ӧ���͵���Сֵ"));
255 OutputString(_T("FLT_UNDERFLOW\r\n"));
256 }
257 return ;
258 case EXCEPTION_INT_OVERFLOW:
259 {
260 //OutputString(_T("INT_OVERFLOW(%s)\r\n"), _T("��������Խ��"));
261 OutputString(_T("INT_OVERFLOW\r\n"));
262 }
263 return ;
264 }
265
266 TCHAR szBuffer[512] = { 0 };
267
268 FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
269 GetModuleHandle( _T("NTDLL.DLL") ),
270 dwExceptionCode, 0, szBuffer, sizeof( szBuffer ), 0 );
271
272 OutputString(_T("%s"), szBuffer);
273 OutputString(_T("\r\n"));
274#endif
275}

References OutputString().

Referenced by ShowExceptionInformation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowLoadModules()

void CBaseException::ShowLoadModules ( )
virtual
87{
88 LoadSymbol();
90 LPMODULE_INFO pmi = pHead;
91
92 TCHAR szBuf[MAX_COMPUTERNAME_LENGTH] = _T("");
93 DWORD dwSize = MAX_COMPUTERNAME_LENGTH;
94 GetUserName(szBuf, &dwSize);
95 OutputString(_T("Current User:%s\r\n"), szBuf);
96 OutputString(_T("BaseAddress:\tSize:\tName\tPath\tSymbolPath\tVersion\r\n"));
97 while (NULL != pmi)
98 {
99 OutputString(_T("%08x\t%d\t%s\t%s\t%s\t%s\r\n"), (unsigned long)(pmi->ModuleAddress), pmi->dwModSize, pmi->szModuleName, pmi->szModulePath, pmi->szSymbolPath, pmi->szVersion);
100 pmi = pmi->pNext;
101 }
102
104}
void FreeModuleInformations(LPMODULE_INFO pmi)
Definition StackWalker.cpp:160
BOOL LoadSymbol()
Definition StackWalker.cpp:41
LPMODULE_INFO GetLoadModules()
Definition StackWalker.cpp:149

References _tag_MODULE_INFO::dwModSize, CStackWalker::FreeModuleInformations(), CStackWalker::GetLoadModules(), CStackWalker::LoadSymbol(), _tag_MODULE_INFO::ModuleAddress, OutputString(), _tag_MODULE_INFO::pNext, _tag_MODULE_INFO::szModuleName, _tag_MODULE_INFO::szModulePath, _tag_MODULE_INFO::szSymbolPath, and _tag_MODULE_INFO::szVersion.

Here is the call graph for this function:

◆ ShowRegistorInformation()

void CBaseException::ShowRegistorInformation ( PCONTEXT pCtx)
virtual
345{
346#if defined(_M_IX86) // Intel Only!
347 OutputString( _T("\nRegisters:\r\n") );
348
349 OutputString(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n"),
350 pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, pCtx->Esi, pCtx->Edi );
351
352 OutputString( _T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip );
353 OutputString( _T("SS:ESP:%04X:%08X EBP:%08X\r\n"),pCtx->SegSs, pCtx->Esp, pCtx->Ebp );
354 OutputString( _T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs );
355 OutputString( _T("Flags:%08X\r\n"), pCtx->EFlags );
356#elif defined(_M_X64)
357 OutputString(_T("\nRegisters:\r\n"));
358
359 OutputString(_T("RAX:%016llX\r\nRBX:%016llX\r\nRCX:%016llX\r\nRDX:%016llX\r\nRSI:%016llX\r\nRDI:%016llX\r\n"),
360 pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx, pCtx->Rsi, pCtx->Rdi );
361
362 OutputString(_T("R8:%016llX\r\nR9:%016llX\r\nR10:%016llX\r\nR11:%016llX\r\nR12:%016llX\r\nR13:%016llX\r\nR14:%016llX\r\nR15:%016llX\r\n"),
363 pCtx->R8, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15 );
364
365 OutputString(_T("CS:RIP:%04X:%016llX\r\n"), pCtx->SegCs, pCtx->Rip);
366 OutputString(_T("SS:RSP:%04X:%016llX RBP:%016llX\r\n"), pCtx->SegSs, pCtx->Rsp, pCtx->Rbp);
367 OutputString(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
368 OutputString(_T("Flags:%08X\r\n"), pCtx->EFlags);
369#elif defined(_M_ARM64)
370 OutputString(_T("\nRegisters:\r\n"));
371 OutputString(_T("PC:%016llX SP:%016llX FP:%016llX LR:%016llX\r\n"),
372 (unsigned long long)pCtx->Pc, (unsigned long long)pCtx->Sp,
373 (unsigned long long)pCtx->Fp, (unsigned long long)pCtx->Lr);
374 OutputString(_T("Cpsr:%08X\r\n"), pCtx->Cpsr);
375#endif
376
377 OutputString( _T("\r\n") );
378}

References OutputString().

Referenced by ShowExceptionInformation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StackWalker()

LPSTACKINFO CStackWalker::StackWalker ( HANDLE hThread = GetCurrentThread(),
const CONTEXT * context = NULL )
inherited
395{
396 //USES_CONVERSION;
397 //加载符号表
398 LoadSymbol();
399
400 LPSTACKINFO pHead = NULL;
401 LPSTACKINFO pTail = pHead;
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 {
413 GET_CURRENT_THREAD_CONTEXT(c, CONTEXT_FULL);
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//intel X86
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 // AMD
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 // ARM64
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 {
482 ZeroMemory(pSym, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
483 ZeroMemory(pLine, sizeof(IMAGEHLP_LINE64));
484
485 pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
486 pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
487 pLine->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
488
489 LPSTACKINFO pCallStack = new STACKINFO;
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 {
496 char szName[STACKWALK_MAX_NAMELEN] = "";
497 StringCchCopy(pCallStack->szFncName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_(pSym->Name));
498 UnDecorateSymbolName(pSym->Name, szName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE);
499 StringCchCopy(pCallStack->undFullName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_(szName));
500 ZeroMemory(szName, STACKWALK_MAX_NAMELEN * sizeof(char));
501 UnDecorateSymbolName(pSym->Name, szName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY);
502 StringCchCopy(pCallStack->undName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_(szName));
503 }else
504 {
505 //调用错误一般是487(地址无效或者没有访问的权限、在符号表中未找到指定地址的相关信息)
506 //this->OutputString(_T("Call SymGetSymFromAddr64 ,Address %08x Error:%08x\n"), sf.AddrPC.Offset, GetLastError());
507
508 StringCchCopy(pCallStack->undFullName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_("Unknown"));
509 }
510
511 if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset, (DWORD*)&dwDisplayment, pLine))
512 {
513 StringCchCopy(pCallStack->szFileName, MAX_PATH, textconv_helper::A2T_(pLine->FileName));
514 pCallStack->uFileNum = pLine->LineNumber;
515 }else
516 {
517 //this->OutputString(_T("Call SymGetLineFromAddr64 ,Address %08x Error:%08x\n"), sf.AddrPC.Offset, GetLastError());
518
519 StringCchCopy(pCallStack->szFileName, MAX_PATH, textconv_helper::A2T_("Unknown file"));
520 pCallStack->uFileNum = -1;
521 }
522
523 //这里为了将获取函数信息失败的情况与正常的情况一起输出,防止用户在查看时出现误解
524 this->OutputString(_T("%08llx:%s [%s][%ld]\n"), pCallStack->szFncAddr, pCallStack->undFullName, pCallStack->szFileName, pCallStack->uFileNum);
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

References GET_CURRENT_THREAD_CONTEXT, LoadSymbol(), m_hProcess, OutputString(), tagSTACKINFO::pNext, STACKWALK_MAX_NAMELEN, tagSTACKINFO::szFileName, tagSTACKINFO::szFncAddr, tagSTACKINFO::szFncName, tagSTACKINFO::uFileNum, tagSTACKINFO::undFullName, and tagSTACKINFO::undName.

Referenced by CBaseException::ShowCallstack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ STF()

void CBaseException::STF ( unsigned int ui,
PEXCEPTION_POINTERS pEp )
static
381{
382 CBaseException base(GetCurrentProcess(), GetCurrentProcessId(), NULL, pEp);
383 throw base;
384}
CBaseException(HANDLE hProcess=GetCurrentProcess(), WORD wPID=GetCurrentProcessId(), LPCTSTR lpSymbolPath=NULL, PEXCEPTION_POINTERS pEp=NULL)
Definition BaseException.cpp:27

References CBaseException().

Here is the call graph for this function:

◆ UnhandledExceptionFilter()

LONG WINAPI CBaseException::UnhandledExceptionFilter ( PEXCEPTION_POINTERS pExceptionInfo)
static
278{
279 if (pExceptionInfo->ExceptionRecord->ExceptionCode < 0x80000000
280 //BBS: Load project on computers with SDC may trigger this exception (in ShowModal()),
281 // It's not fatal and should be ignored, or there will be lots of meaningless crash logs
282 || pExceptionInfo->ExceptionRecord->ExceptionCode==0xe0434352)
283 //BBS: ignore the exception when copy preset
284 //|| pExceptionInfo->ExceptionRecord->ExceptionCode==0xe06d7363)
285 {
286 //BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": got an ExceptionCode %1%, skip it!") % pExceptionInfo->ExceptionRecord->ExceptionCode;
287 return EXCEPTION_CONTINUE_SEARCH;
288 }
289 g_dump_mutex.lock();
290 CBaseException base(GetCurrentProcess(), GetCurrentProcessId(), NULL, pExceptionInfo);
291 base.ShowExceptionInformation();
292 g_dump_mutex.unlock();
293
294 return EXCEPTION_CONTINUE_SEARCH;
295}
static std::mutex g_dump_mutex
Definition BaseException.cpp:25

References CBaseException(), g_dump_mutex, and ShowExceptionInformation().

Here is the call graph for this function:

◆ UnhandledExceptionFilter2()

LONG WINAPI CBaseException::UnhandledExceptionFilter2 ( PEXCEPTION_POINTERS pExceptionInfo)
static
298{
299 CBaseException base(GetCurrentProcess(), GetCurrentProcessId(), NULL, pExceptionInfo);
300 base.ShowExceptionInformation();
301
302 return EXCEPTION_CONTINUE_SEARCH;
303}

References CBaseException(), and ShowExceptionInformation().

Here is the call graph for this function:

Member Data Documentation

◆ m_bSymbolLoaded

BOOL CStackWalker::m_bSymbolLoaded
protectedinherited

◆ m_hProcess

HANDLE CStackWalker::m_hProcess
protectedinherited

◆ m_lpszSymbolPath

LPTSTR CStackWalker::m_lpszSymbolPath
protectedinherited

◆ m_pEp

PEXCEPTION_POINTERS CBaseException::m_pEp
protected

◆ m_wPID

WORD CStackWalker::m_wPID
protectedinherited

Referenced by CStackWalker(), and GetModulesTH32().

◆ output_file

boost::nowide::ofstream* CBaseException::output_file
protected

The documentation for this class was generated from the following files: