mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-20 07:22:35 +00:00
build: clear eleven single-site clang-cl warning categories Each of these is the last site left in its category, and every one is the compiler saying it cannot tell what the code meant. Nothing here changes defined behavior. - OrcaSlicer_app_msvc.cpp printed a DWORD with %d - StackWalker.cpp ran delete[] through an LPVOID - ToolOrdering.cpp used a bare ; as a deliberate skip loop's body - WipeTower.cpp had finish_block_tcr = finish_block_tcr, so the branch that reached it did nothing. Folding the condition into the enclosing if leaves the other branch untouched - GCodeProcessor.cpp had an else binding to the inner if while the outer if carried no braces - AmsMappingPopupUpdate.cpp wrote >= 1 || <= 3 where its own comment says && - CalibrationWizardPresetPage.cpp left max_decimal_length unset through a pair of conditions that cover every value but not visibly so - DevManager.cpp bound map elements to pair<K, V> rather than pair<const K, V>, copying every one - SyncAmsInfoDialog.cpp had extraneous parentheses around a comparison - Http.cpp had if (speed > 0.01) speed = speed;. speed now starts at 0 as well, because curl_easy_getinfo leaves the target untouched when it fails and the value reaches Progress either way - SnapmakerPrinterAgent.cpp truncated npos into an unsigned int, so the != npos guard was always true. A colour with no # still yields 0, because the wrap produced 0 as well Nine categories go to zero. -Wtautological-overlap-compare and -Wsometimes-uninitialized reach zero when #15583 merges their second site.
550 lines
16 KiB
C++
550 lines
16 KiB
C++
#include "StackWalker.h"
|
|
#include <strsafe.h>
|
|
//#include <atlconv.h>
|
|
#include <dbghelp.h>
|
|
#pragma comment(lib, "version.lib")
|
|
#pragma comment( lib, "dbghelp.lib" )
|
|
|
|
CStackWalker::CStackWalker(HANDLE hProcess, WORD wPID, LPCTSTR lpSymbolPath):
|
|
m_hProcess(hProcess),
|
|
m_wPID(wPID),
|
|
m_bSymbolLoaded(FALSE),
|
|
m_lpszSymbolPath(NULL)
|
|
{
|
|
if (NULL != lpSymbolPath)
|
|
{
|
|
size_t dwLength = 0;
|
|
StringCchLength(lpSymbolPath, MAX_SYMBOL_PATH, &dwLength);
|
|
m_lpszSymbolPath = new TCHAR[dwLength + 1];
|
|
ZeroMemory(m_lpszSymbolPath, sizeof(TCHAR) * (dwLength + 1));
|
|
StringCchCopy(m_lpszSymbolPath, dwLength, lpSymbolPath);
|
|
}
|
|
|
|
}
|
|
|
|
CStackWalker::~CStackWalker(void)
|
|
{
|
|
if (NULL != m_lpszSymbolPath)
|
|
{
|
|
delete[] m_lpszSymbolPath;
|
|
}
|
|
|
|
if (m_bSymbolLoaded)
|
|
{
|
|
SymCleanup(m_hProcess);
|
|
}
|
|
}
|
|
|
|
BOOL CStackWalker::LoadSymbol()
|
|
{
|
|
//USES_CONVERSION;
|
|
//只加载一次
|
|
if(m_bSymbolLoaded)
|
|
{
|
|
return m_bSymbolLoaded;
|
|
}
|
|
|
|
if (NULL != m_lpszSymbolPath)
|
|
{
|
|
|
|
m_bSymbolLoaded = SymInitialize(m_hProcess, textconv_helper::T2A_(m_lpszSymbolPath), FALSE);
|
|
return m_bSymbolLoaded;
|
|
}
|
|
|
|
//添加当前程序路径
|
|
TCHAR szSymbolPath[MAX_SYMBOL_PATH] = _T("");
|
|
StringCchCopy(szSymbolPath, MAX_SYMBOL_PATH, _T(".;"));
|
|
|
|
//添加程序所在目录
|
|
TCHAR szTemp[MAX_PATH] = _T("");
|
|
if (GetCurrentDirectory(MAX_PATH, szTemp) > 0)
|
|
{
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
|
|
}
|
|
|
|
//添加程序主模块所在路径
|
|
ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
|
|
if (GetModuleFileName(NULL, szTemp, MAX_PATH) > 0)
|
|
{
|
|
size_t sLength = 0;
|
|
StringCchLength(szTemp, MAX_PATH, &sLength);
|
|
for (int i = sLength; i >= 0; i--)
|
|
{
|
|
if (szTemp[i] == _T('\\') || szTemp[i] == _T('/') || szTemp[i] == _T(':'))
|
|
{
|
|
szTemp[i] = _T('\0');
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
|
|
|
|
ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
|
|
if (GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), szTemp, MAX_PATH) > 0)
|
|
{
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
|
|
}
|
|
|
|
ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
|
|
if (GetEnvironmentVariable(_T("_NT_ALTERNATE_SYMBOL_PATH"), szTemp, MAX_PATH) > 0)
|
|
{
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
|
|
}
|
|
|
|
ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
|
|
if (GetEnvironmentVariable(_T("SYSTEMROOT"), szTemp, MAX_PATH) > 0)
|
|
{
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
|
|
// also add the "system32"-directory:
|
|
StringCchCat(szTemp, MAX_PATH, _T("\\system32"));
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T(";"));
|
|
}
|
|
|
|
ZeroMemory(szTemp, MAX_PATH * sizeof(TCHAR));
|
|
if (GetEnvironmentVariable(_T("SYSTEMDRIVE"), szTemp, MAX_PATH) > 0)
|
|
{
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("SRV*"));
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, szTemp);
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("\\websymbols"));
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("*http://msdl.microsoft.com/download/symbols;"));
|
|
}
|
|
else
|
|
{
|
|
StringCchCat(szSymbolPath, MAX_SYMBOL_PATH, _T("SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"));
|
|
}
|
|
|
|
size_t sLength = 0;
|
|
StringCchLength(szSymbolPath, MAX_SYMBOL_PATH, &sLength);
|
|
if (sLength > 0)
|
|
{
|
|
m_lpszSymbolPath = new TCHAR[sLength + 1];
|
|
ZeroMemory(m_lpszSymbolPath, sizeof(TCHAR) * (sLength + 1));
|
|
StringCchCopy(m_lpszSymbolPath, sLength, szSymbolPath);
|
|
}
|
|
|
|
if (NULL != m_lpszSymbolPath)
|
|
{
|
|
m_bSymbolLoaded = SymInitialize(m_hProcess, textconv_helper::T2A_(m_lpszSymbolPath), TRUE); //这里设置为TRUE,让它在初始化符号表的同时加载符号表
|
|
}
|
|
|
|
DWORD symOptions = SymGetOptions();
|
|
symOptions |= SYMOPT_LOAD_LINES;
|
|
symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
|
|
symOptions |= SYMOPT_DEBUG;
|
|
SymSetOptions(symOptions);
|
|
|
|
return m_bSymbolLoaded;
|
|
}
|
|
|
|
LPMODULE_INFO CStackWalker::GetLoadModules()
|
|
{
|
|
LPMODULE_INFO pHead = GetModulesTH32();
|
|
if (NULL == pHead)
|
|
{
|
|
pHead = GetModulesPSAPI();
|
|
}
|
|
|
|
return pHead;
|
|
}
|
|
|
|
void CStackWalker::FreeModuleInformations(LPMODULE_INFO pmi)
|
|
{
|
|
LPMODULE_INFO head = pmi;
|
|
while (NULL != head)
|
|
{
|
|
pmi = pmi->pNext;
|
|
delete head;
|
|
head = pmi;
|
|
}
|
|
}
|
|
|
|
LPMODULE_INFO CStackWalker::GetModulesTH32()
|
|
{
|
|
//这里为了防止加载Toolhelp.dll 影响最终结果,所以采用动态加载的方式
|
|
LPMODULE_INFO pHead = NULL;
|
|
LPMODULE_INFO pTail = pHead;
|
|
|
|
typedef HANDLE (WINAPI *pfnCreateToolhelp32Snapshot)(DWORD dwFlags, DWORD th32ProcessID);
|
|
typedef BOOL (WINAPI *pfnModule32First)(HANDLE hSnapshot, LPMODULEENTRY32 lpme );
|
|
typedef BOOL (WINAPI *pfnModule32Next)(HANDLE hSnapshot, LPMODULEENTRY32 lpme );
|
|
|
|
const TCHAR* dllname[] = {_T("kernel32.dll"), _T("tlhelp32.dll")};
|
|
HINSTANCE hToolhelp = NULL;
|
|
|
|
pfnCreateToolhelp32Snapshot CreateToolhelp32Snapshot = NULL;
|
|
pfnModule32First Module32First = NULL;
|
|
pfnModule32Next Module32Next = NULL;
|
|
|
|
HANDLE hSnap;
|
|
MODULEENTRY32 me;
|
|
me.dwSize = sizeof(me);
|
|
BOOL keepGoing;
|
|
size_t i;
|
|
|
|
for (i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
|
|
{
|
|
hToolhelp = LoadLibrary(dllname[i]);
|
|
if (hToolhelp == NULL)
|
|
continue;
|
|
CreateToolhelp32Snapshot = (pfnCreateToolhelp32Snapshot)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
|
|
#ifdef UNICODE
|
|
Module32First = (pfnModule32First)GetProcAddress(hToolhelp, "Module32FirstW");
|
|
Module32Next = (pfnModule32Next)GetProcAddress(hToolhelp, "Module32NextW");
|
|
#else
|
|
Module32First = (pfnModule32First)GetProcAddress(hToolhelp, "Module32FirstA");
|
|
Module32Next = (pfnModule32Next)GetProcAddress(hToolhelp, "Module32NextA");
|
|
#endif
|
|
|
|
if ((CreateToolhelp32Snapshot != NULL) && (Module32First != NULL) && (Module32Next != NULL))
|
|
break;
|
|
|
|
FreeLibrary(hToolhelp);
|
|
hToolhelp = NULL;
|
|
}
|
|
|
|
if (hToolhelp == NULL)
|
|
return pHead;
|
|
|
|
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_wPID);
|
|
|
|
if (hSnap == INVALID_HANDLE_VALUE)
|
|
{
|
|
FreeLibrary(hToolhelp);
|
|
return pHead;
|
|
}
|
|
|
|
keepGoing = Module32First(hSnap, &me);
|
|
|
|
while (keepGoing)
|
|
{
|
|
LPMODULE_INFO pmi = new MODULE_INFO;
|
|
ZeroMemory(pmi, sizeof(MODULE_INFO));
|
|
|
|
pmi->dwModSize = me.modBaseSize;
|
|
pmi->ModuleAddress = (DWORD64)me.modBaseAddr;
|
|
StringCchCopy(pmi->szModuleName, MAX_MODULE_NAME32, me.szModule);
|
|
StringCchCopy(pmi->szModulePath, MAX_PATH, me.szExePath);
|
|
GetModuleInformation(pmi);
|
|
if (pHead == NULL)
|
|
{
|
|
pHead = pmi;
|
|
pTail = pHead;
|
|
}else
|
|
{
|
|
pTail->pNext = pmi;
|
|
pTail = pmi;
|
|
}
|
|
|
|
keepGoing = Module32Next(hSnap, &me);
|
|
}
|
|
|
|
CloseHandle(hSnap);
|
|
FreeLibrary(hToolhelp);
|
|
return pHead;
|
|
}
|
|
|
|
LPMODULE_INFO CStackWalker::GetModulesPSAPI()
|
|
{
|
|
LPMODULE_INFO pHead = NULL;
|
|
LPMODULE_INFO pTail = pHead;
|
|
typedef BOOL(WINAPI *pfnEnumProcessModules)(HANDLE hProcess, HMODULE * lphModule, DWORD cb,LPDWORD lpcbNeeded);
|
|
typedef DWORD(WINAPI *pfnGetModuleFileNameEx)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
|
|
typedef DWORD(WINAPI *pfnGetModuleBaseName)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
|
|
typedef BOOL(WINAPI *pfnGetModuleInformation)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize);
|
|
|
|
HINSTANCE hPsapi;
|
|
pfnEnumProcessModules EnumProcessModules = NULL;
|
|
pfnGetModuleFileNameEx GetModuleFileNameEx = NULL;
|
|
pfnGetModuleBaseName GetModuleBaseName = NULL;
|
|
pfnGetModuleInformation GetModuleInformation = NULL;
|
|
|
|
DWORD i;
|
|
//ModuleEntry e;
|
|
DWORD cbNeeded;
|
|
MODULEINFO mi;
|
|
HMODULE* hMods = NULL;
|
|
TCHAR szModuleName[MAX_MODULE_NAME32 + 1] = _T("");
|
|
TCHAR szModulePath[MAX_PATH] = _T("");
|
|
|
|
hPsapi = LoadLibrary(_T("psapi.dll"));
|
|
if (hPsapi == NULL)
|
|
{
|
|
return pHead;
|
|
}
|
|
|
|
EnumProcessModules = (pfnEnumProcessModules)GetProcAddress(hPsapi, "EnumProcessModules");
|
|
#ifdef UNICODE
|
|
GetModuleFileNameEx = (pfnGetModuleFileNameEx)GetProcAddress(hPsapi, "GetModuleFileNameExW");
|
|
GetModuleBaseName = (pfnGetModuleBaseName)GetProcAddress(hPsapi, "GetModuleBaseNameW");
|
|
#else
|
|
GetModuleFileNameEx = (pfnGetModuleFileNameEx)GetProcAddress(hPsapi, "GetModuleFileNameExA");
|
|
GetModuleBaseName = (pfnGetModuleBaseName)GetProcAddress(hPsapi, "GetModuleBaseNameA");
|
|
#endif
|
|
GetModuleInformation = (pfnGetModuleInformation)GetProcAddress(hPsapi, "GetModuleInformation");
|
|
if ((EnumProcessModules == NULL) || (GetModuleFileNameEx == NULL) || (GetModuleBaseName == NULL) || (GetModuleInformation == NULL))
|
|
{
|
|
FreeLibrary(hPsapi);
|
|
return pHead;
|
|
}
|
|
|
|
EnumProcessModules(m_hProcess, hMods, 0, &cbNeeded);
|
|
hMods = new HMODULE[cbNeeded / sizeof(HMODULE)];
|
|
ASSERT(NULL != hMods);
|
|
ZeroMemory(hMods, cbNeeded);
|
|
|
|
if (!EnumProcessModules(m_hProcess, hMods, cbNeeded, &cbNeeded))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
for (i = 0; i < cbNeeded / sizeof(HMODULE); i++)
|
|
{
|
|
GetModuleInformation(m_hProcess, hMods[i], &mi, sizeof(mi));
|
|
GetModuleFileNameEx(m_hProcess, hMods[i], szModulePath, MAX_PATH);
|
|
GetModuleBaseName(m_hProcess, hMods[i], szModuleName, MAX_MODULE_NAME32);
|
|
LPMODULE_INFO pmi = new MODULE_INFO;
|
|
ZeroMemory(pmi, sizeof(MODULE_INFO));
|
|
pmi->dwModSize = mi.SizeOfImage;
|
|
pmi->ModuleAddress = (DWORD64)mi.lpBaseOfDll;
|
|
StringCchCopy(pmi->szModuleName, MAX_MODULE_NAME32, szModuleName);
|
|
StringCchCopy(pmi->szModulePath, MAX_PATH, szModulePath);
|
|
this->GetModuleInformation(pmi);
|
|
if (pHead == NULL)
|
|
{
|
|
pHead = pmi;
|
|
pTail = pHead;
|
|
}else
|
|
{
|
|
pTail->pNext = pmi;
|
|
pTail = pmi;
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
if (hPsapi != NULL)
|
|
{
|
|
FreeLibrary(hPsapi);
|
|
}
|
|
if (hMods != NULL)
|
|
{
|
|
delete[] hMods;
|
|
}
|
|
|
|
return pHead;
|
|
}
|
|
|
|
void CStackWalker::OutputString(LPCTSTR lpszFormat, ...)
|
|
{
|
|
TCHAR szBuf[1024] = _T("");
|
|
va_list args;
|
|
va_start(args, lpszFormat);
|
|
_vsntprintf_s(szBuf, 1024, lpszFormat, args);
|
|
va_end(args);
|
|
|
|
OutputDebugString(szBuf);
|
|
}
|
|
|
|
void CStackWalker::GetModuleInformation(LPMODULE_INFO pmi)
|
|
{
|
|
//USES_CONVERSION;
|
|
IMAGEHLP_MODULE64 im = {0};
|
|
im.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
|
|
|
|
VS_FIXEDFILEINFO* pvfi = NULL;
|
|
DWORD dwHandle = 0;
|
|
DWORD dwInfoSize = 0;
|
|
dwInfoSize = GetFileVersionInfoSize(pmi->szModulePath, &dwHandle);
|
|
|
|
if (dwInfoSize > 0)
|
|
{
|
|
byte *lpData = new byte[dwInfoSize];
|
|
ZeroMemory(lpData, dwInfoSize * sizeof(byte));
|
|
|
|
if (GetFileVersionInfo(pmi->szModulePath, dwHandle, dwInfoSize, lpData) > 0 )
|
|
{
|
|
TCHAR szBlock[] = _T("\\");
|
|
UINT len;
|
|
if (VerQueryValue(lpData, szBlock, (LPVOID*)&pvfi, &len))
|
|
{
|
|
WORD v1 = HIWORD(pvfi->dwFileVersionMS);
|
|
WORD v2 = LOWORD(pvfi->dwFileVersionMS);
|
|
WORD v3 = HIWORD(pvfi->dwFileVersionLS);
|
|
WORD v4 = LOWORD(pvfi->dwFileVersionLS);
|
|
_stprintf_s(pmi->szVersion, MAX_VERSION_LENGTH, _T("%d.%d.%d.%d"), v1, v2, v3, v4);
|
|
}
|
|
}
|
|
|
|
delete[] lpData;
|
|
}
|
|
|
|
SymGetModuleInfo64(m_hProcess, pmi->ModuleAddress, &im);
|
|
StringCchCopy(pmi->szSymbolPath, MAX_PATH, textconv_helper::A2T_(im.LoadedPdbName));
|
|
}
|
|
|
|
LPSTACKINFO CStackWalker::StackWalker(HANDLE hThread, const CONTEXT* context)
|
|
{
|
|
//USES_CONVERSION;
|
|
//加载符号表
|
|
LoadSymbol();
|
|
|
|
LPSTACKINFO pHead = NULL;
|
|
LPSTACKINFO pTail = pHead;
|
|
|
|
//获取当前线程的上下文环境
|
|
CONTEXT c = {0};
|
|
if (context == NULL)
|
|
{
|
|
#if _WIN32_WINNT <= 0x0501
|
|
if (hThread == GetCurrentThread())
|
|
#else
|
|
if (GetThreadId(hThread) == GetCurrentThreadId())
|
|
#endif
|
|
{
|
|
GET_CURRENT_THREAD_CONTEXT(c, CONTEXT_FULL);
|
|
}
|
|
else
|
|
{
|
|
//如果不是当前线程,需要停止目标线程,以便取出正确的堆栈信息
|
|
SuspendThread(hThread);
|
|
memset(&c, 0, sizeof(CONTEXT));
|
|
c.ContextFlags = CONTEXT_FULL;
|
|
if (GetThreadContext(hThread, &c) == FALSE)
|
|
{
|
|
ResumeThread(hThread);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
c = *context;
|
|
|
|
STACKFRAME64 sf = {0};
|
|
DWORD imageType;
|
|
|
|
//intel X86
|
|
#ifdef _M_IX86
|
|
imageType = IMAGE_FILE_MACHINE_I386;
|
|
sf.AddrPC.Offset = c.Eip;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
sf.AddrFrame.Offset = c.Ebp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrStack.Offset = c.Esp;
|
|
sf.AddrStack.Mode = AddrModeFlat;
|
|
// AMD
|
|
#elif _M_X64
|
|
imageType = IMAGE_FILE_MACHINE_AMD64;
|
|
sf.AddrPC.Offset = c.Rip;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
sf.AddrFrame.Offset = c.Rsp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrStack.Offset = c.Rsp;
|
|
sf.AddrStack.Mode = AddrModeFlat;
|
|
////intel Itanium(安腾)
|
|
#elif _M_IA64
|
|
imageType = IMAGE_FILE_MACHINE_IA64;
|
|
sf.AddrPC.Offset = c.StIIP;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
sf.AddrFrame.Offset = c.IntSp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrBStore.Offset = c.RsBSP;
|
|
sf.AddrBStore.Mode = AddrModeFlat;
|
|
sf.AddrStack.Offset = c.IntSp;
|
|
sf.AddrStack.Mode = AddrModeFlat;
|
|
// ARM64
|
|
#elif defined(_M_ARM64)
|
|
imageType = IMAGE_FILE_MACHINE_ARM64;
|
|
sf.AddrPC.Offset = c.Pc;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
sf.AddrFrame.Offset = c.Fp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrStack.Offset = c.Sp;
|
|
sf.AddrStack.Mode = AddrModeFlat;
|
|
#else
|
|
#error "Platform not supported!"
|
|
#endif
|
|
|
|
|
|
DWORD64 dwDisplayment = 0;
|
|
PIMAGEHLP_SYMBOL64 pSym = (PIMAGEHLP_SYMBOL64)new BYTE[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
|
|
PIMAGEHLP_LINE64 pLine = new IMAGEHLP_LINE64;
|
|
while (StackWalk64(imageType, m_hProcess, hThread, &sf, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
|
|
{
|
|
ZeroMemory(pSym, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
|
|
ZeroMemory(pLine, sizeof(IMAGEHLP_LINE64));
|
|
|
|
pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
|
|
pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
|
|
pLine->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
|
|
|
LPSTACKINFO pCallStack = new STACKINFO;
|
|
ZeroMemory(pCallStack, sizeof(STACKINFO));
|
|
pCallStack->szFncAddr = sf.AddrPC.Offset;
|
|
if (sf.AddrPC.Offset != 0)
|
|
{
|
|
if(SymGetSymFromAddr64(m_hProcess, sf.AddrPC.Offset, &dwDisplayment, pSym))
|
|
{
|
|
char szName[STACKWALK_MAX_NAMELEN] = "";
|
|
StringCchCopy(pCallStack->szFncName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_(pSym->Name));
|
|
UnDecorateSymbolName(pSym->Name, szName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE);
|
|
StringCchCopy(pCallStack->undFullName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_(szName));
|
|
ZeroMemory(szName, STACKWALK_MAX_NAMELEN * sizeof(char));
|
|
UnDecorateSymbolName(pSym->Name, szName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY);
|
|
StringCchCopy(pCallStack->undName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_(szName));
|
|
}else
|
|
{
|
|
//调用错误一般是487(地址无效或者没有访问的权限、在符号表中未找到指定地址的相关信息)
|
|
//this->OutputString(_T("Call SymGetSymFromAddr64 ,Address %08x Error:%08x\n"), sf.AddrPC.Offset, GetLastError());
|
|
|
|
StringCchCopy(pCallStack->undFullName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_("Unknown"));
|
|
}
|
|
|
|
if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset, (DWORD*)&dwDisplayment, pLine))
|
|
{
|
|
StringCchCopy(pCallStack->szFileName, MAX_PATH, textconv_helper::A2T_(pLine->FileName));
|
|
pCallStack->uFileNum = pLine->LineNumber;
|
|
}else
|
|
{
|
|
//this->OutputString(_T("Call SymGetLineFromAddr64 ,Address %08x Error:%08x\n"), sf.AddrPC.Offset, GetLastError());
|
|
|
|
StringCchCopy(pCallStack->szFileName, MAX_PATH, textconv_helper::A2T_("Unknown file"));
|
|
pCallStack->uFileNum = -1;
|
|
}
|
|
|
|
//这里为了将获取函数信息失败的情况与正常的情况一起输出,防止用户在查看时出现误解
|
|
this->OutputString(_T("%08llx:%s [%s][%ld]\n"), pCallStack->szFncAddr, pCallStack->undFullName, pCallStack->szFileName, pCallStack->uFileNum);
|
|
if (NULL == pHead)
|
|
{
|
|
pHead = pCallStack;
|
|
pTail = pHead;
|
|
}else
|
|
{
|
|
pTail->pNext = pCallStack;
|
|
pTail = pCallStack;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] pSym;
|
|
delete pLine;
|
|
|
|
return pHead;
|
|
}
|
|
|
|
void CStackWalker::FreeStackInformations(LPSTACKINFO psi)
|
|
{
|
|
LPSTACKINFO head = psi;
|
|
while (NULL != head)
|
|
{
|
|
psi = psi->pNext;
|
|
delete head;
|
|
head = psi;
|
|
}
|
|
|
|
} |