static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) { #ifdef _WIN32 static HANDLE stack_process_handle = NULL; DWORD64 index; IMAGEHLP_LINEW64 line; struct { SYMBOL_INFOW sym; uchar buffer[256]; } data; data.sym.SizeOfStruct = sizeof(data.sym); data.sym.MaxNameLen = 255; if( !stack_process_handle ) { stack_process_handle = GetCurrentProcess(); SymSetOptions(SYMOPT_LOAD_LINES); SymInitialize(stack_process_handle,NULL,TRUE); } if( SymFromAddrW(stack_process_handle,(DWORD64)(int_val)addr,&index,&data.sym) ) { DWORD offset = 0; line.SizeOfStruct = sizeof(line); line.FileName = USTR("\\?"); line.LineNumber = 0; SymGetLineFromAddrW64(stack_process_handle, (DWORD64)(int_val)addr, &offset, &line); *outSize = usprintf(out,*outSize,USTR("%s(%s:%d)"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber); return out; } #endif return NULL; }
void CException::FillStackTrace(void) { // This must be loaded upon apps start // SymSetOptions(SYMOPT_LOAD_LINES); UINT i; LPVOID stack[1024]; USHORT frames; PSYMBOL_INFOW symbol; HANDLE process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); frames = CaptureStackBackTrace(0, 1024, stack, NULL); symbol = (PSYMBOL_INFOW) malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * sizeof(TCHAR)); ZeroMemory(symbol, sizeof(SYMBOL_INFOW) + MAX_PATH * sizeof(TCHAR)); symbol->MaxNameLen = MAX_PATH; symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); for (i = 0; i < frames; i++) { SymFromAddrW(process, (DWORD64)(stack[i]), 0, symbol); printf("%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address); } free(symbol); }
/* static */ BOOL wxDbgHelpDLL::CallSymFromAddr(HANDLE hProcess, DWORD64 Address, size_t* offset, wxString* name) { DWORD64 dwDisplacement; #ifdef UNICODE if ( SymFromAddrW ) { VarSizedStruct<SYMBOL_INFOW> infoW; if ( SymFromAddrW(hProcess, Address, &dwDisplacement, infoW) ) { *offset = dwDisplacement; *name = infoW->Name; return TRUE; } } #endif // UNICODE if ( SymFromAddr ) { VarSizedStruct<SYMBOL_INFO> info; if ( SymFromAddr(hProcess, Address, &dwDisplacement, info) ) { *offset = dwDisplacement; *name = info->Name; return TRUE; } } return FALSE; }
static void print_stack_from_context(CONTEXT c) { STACKFRAME s; // in/out stackframe memset(&s, 0, sizeof(s)); DWORD imageType; #ifdef _M_IX86 // normally, call ImageNtHeader() and use machine info from PE header imageType = IMAGE_FILE_MACHINE_I386; s.AddrPC.Offset = c.Eip; s.AddrPC.Mode = AddrModeFlat; s.AddrFrame.Offset = c.Ebp; s.AddrFrame.Mode = AddrModeFlat; s.AddrStack.Offset = c.Esp; s.AddrStack.Mode = AddrModeFlat; #elif _M_X64 imageType = IMAGE_FILE_MACHINE_AMD64; s.AddrPC.Offset = c.Rip; s.AddrPC.Mode = AddrModeFlat; s.AddrFrame.Offset = c.Rsp; s.AddrFrame.Mode = AddrModeFlat; s.AddrStack.Offset = c.Rsp; s.AddrStack.Mode = AddrModeFlat; #elif _M_IA64 imageType = IMAGE_FILE_MACHINE_IA64; s.AddrPC.Offset = c.StIIP; s.AddrPC.Mode = AddrModeFlat; s.AddrFrame.Offset = c.IntSp; s.AddrFrame.Mode = AddrModeFlat; s.AddrBStore.Offset = c.RsBSP; s.AddrBStore.Mode = AddrModeFlat; s.AddrStack.Offset = c.IntSp; s.AddrStack.Mode = AddrModeFlat; #else #error "Platform not supported!" #endif HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); SYMBOL_INFOW *symbol = (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); while (StackWalk(imageType, process, thread, &s, &c, 0, SymFunctionTableAccess, SymGetModuleBase, 0)) { BOOL has_symbol = SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol); fwprintf( stderr, L"*** %016I64X %ls - %016I64X\n", (DWORD64)(s.AddrPC.Offset), has_symbol ? symbol->Name : L"<<no symbol>>", (DWORD64)symbol->Address); fflush(stderr); } free(symbol); }
const Symbol * const SymEngine::GetSymbol(DWORD64 dwAddress) { if (dwAddress == 0) return nullptr; Symbol& symbol = cache[dwAddress]; if (symbol.address != 0) return &symbol; if (!isInitialized) return nullptr; symbol.address = dwAddress; // Module Name IMAGEHLP_MODULEW64 moduleInfo; memset(&moduleInfo, 0, sizeof(IMAGEHLP_MODULEW64)); moduleInfo.SizeOfStruct = sizeof(moduleInfo); if (SymGetModuleInfoW64(hProcess, dwAddress, &moduleInfo)) { symbol.module = moduleInfo.ImageName; } // FileName and Line IMAGEHLP_LINEW64 lineInfo; memset(&lineInfo, 0, sizeof(IMAGEHLP_LINEW64)); lineInfo.SizeOfStruct = sizeof(lineInfo); DWORD dwDisp; if (SymGetLineFromAddrW64(hProcess, dwAddress, &dwDisp, &lineInfo)) { symbol.file = lineInfo.FileName; symbol.line = lineInfo.LineNumber; } const size_t length = (sizeof(SYMBOL_INFOW) + MAX_SYM_NAME*sizeof(WCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64) + 1; // Function Name ULONG64 buffer[length]; PSYMBOL_INFOW dbgSymbol = (PSYMBOL_INFOW)buffer; memset(dbgSymbol, 0, sizeof(buffer)); dbgSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW); dbgSymbol->MaxNameLen = MAX_SYM_NAME; if (SymFromAddrW(hProcess, dwAddress, &symbol.offset, dbgSymbol)) { symbol.function.resize(dbgSymbol->NameLen); memcpy(&symbol.function[0], &dbgSymbol->Name[0], sizeof(WCHAR) * dbgSymbol->NameLen); } return &symbol; }
static void print_current_stack() { typedef USHORT(WINAPI * CaptureStackBackTraceType)( __in ULONG, __in ULONG, __out PVOID *, __out_opt PULONG); CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress( LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace")); if (func == NULL) return; // WOE 29.SEP.2010 // Quote from Microsoft Documentation: // ## Windows Server 2003 and Windows XP: // ## The sum of the FramesToSkip and FramesToCapture parameters must be less // than 63. #define MAX_CALLERS 62 void *callers_stack[MAX_CALLERS]; unsigned short frames; SYMBOL_INFOW *symbol; HANDLE process; process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); frames = (func)(0, MAX_CALLERS, callers_stack, NULL); symbol = (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); const unsigned short MAX_CALLERS_SHOWN = 32; frames = frames < MAX_CALLERS_SHOWN ? frames : MAX_CALLERS_SHOWN; for (unsigned int i = 0; i < frames; i++) { SymFromAddrW(process, (DWORD64)(callers_stack[i]), 0, symbol); fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X\n", i, (DWORD64)callers_stack[i], symbol->Name, (DWORD64)symbol->Address); fflush(stderr); } free(symbol); }
// Resolve - Creates a nicely formatted rendition of the CallStack, including // symbolic information (function names and line numbers) if available. and // saves it for later retrieval. This is almost identical to Callstack::dump above. // // Note: The symbol handler must be initialized prior to calling this // function. // // - showInternalFrames (IN): If true, then all frames in the CallStack will be // dumped. Otherwise, frames internal to the heap will not be dumped. // // Return Value: // // None. // void CallStack::resolve(BOOL showInternalFrames) { if (m_resolved) { // already resolved, no need to do it again // resolving twice may report an incorrect module for the stack frames // if the memory was leaked in a dynamic library that was already unloaded. return; } if (m_status & CALLSTACK_STATUS_INCOMPLETE) { // This call stack appears to be incomplete. Using StackWalk64 may be // more reliable. Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" L" complete stack trace.\n"); } IMAGEHLP_LINE64 sourceInfo = { 0 }; sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; WCHAR callingModuleName [MAX_PATH] = L""; WCHAR lowerCaseName [MAX_PATH]; const size_t max_line_length = MAXREPORTLENGTH + 1; m_resolvedCapacity = m_size * max_line_length; m_resolved = new WCHAR[m_resolvedCapacity]; const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); ZeroMemory(m_resolved, allocedBytes); // Iterate through each frame in the call stack. for (UINT32 frame = 0; frame < m_size; frame++) { // Try to get the source file and line number associated with // this program counter address. SIZE_T programCounter = (*this)[frame]; g_symbolLock.Enter(); BOOL foundline = FALSE; DWORD displacement = 0; // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. // When that happens there is nothing we can do except crash. DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo); assert(m_resolved != NULL); if (foundline && !showInternalFrames) { wcscpy_s(lowerCaseName, sourceInfo.FileName); _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1); if (isInternalModule(lowerCaseName)) { // Don't show frames in files internal to the heap. g_symbolLock.Leave(); continue; } } // Initialize structures passed to the symbol handler. SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer; functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; // Try to get the name of the function containing this program // counter address. DWORD64 displacement64 = 0; LPWSTR functionName; DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) { functionName = functionInfo->Name; } else { // GetFormattedMessage( GetLastError() ); functionName = L"(Function name unavailable)"; displacement64 = 0; } g_symbolLock.Leave(); HMODULE hCallingModule = GetCallingModule(programCounter); LPWSTR moduleName = L"(Module name unavailable)"; if (hCallingModule && GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) { moduleName = wcsrchr(callingModuleName, L'\\'); if (moduleName == NULL) moduleName = wcsrchr(callingModuleName, L'/'); if (moduleName != NULL) moduleName++; else moduleName = callingModuleName; } // Use static here to increase performance, and avoid heap allocs. Hopefully this won't // prove to be an issue in thread safety. If it does, it will have to be simply non-static. static WCHAR stack_line[max_line_length] = L""; int NumChars = -1; // Display the current stack frame's information. if (foundline) { // Just truncate anything that is too long. if (displacement == 0) NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" %s (%d): %s!%s\n", sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName); else NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" %s (%d): %s!%s + 0x%X bytes\n", sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement); } else { if (displacement64 == 0) NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", programCounter, moduleName, functionName); else NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", programCounter, moduleName, functionName, (DWORD)displacement64); } if (NumChars >= 0) { assert(m_resolved != NULL); m_resolvedLength += NumChars; wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); } } // end for loop }
// dump - Dumps a nicely formatted rendition of the CallStack, including // symbolic information (function names and line numbers) if available. // // Note: The symbol handler must be initialized prior to calling this // function. // // - showinternalframes (IN): If true, then all frames in the CallStack will be // dumped. Otherwise, frames internal to the heap will not be dumped. // // Return Value: // // None. // void CallStack::dump(BOOL showInternalFrames, UINT start_frame) const { // The stack was dumped already if (m_resolved) { dumpResolved(); return; } if (m_status & CALLSTACK_STATUS_INCOMPLETE) { // This call stack appears to be incomplete. Using StackWalk64 may be // more reliable. Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" L" complete stack trace.\n"); } IMAGEHLP_LINE64 sourceInfo = { 0 }; sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; WCHAR lowerCaseName [MAX_PATH]; WCHAR callingModuleName [MAX_PATH]; const size_t max_size = MAXREPORTLENGTH + 1; // Iterate through each frame in the call stack. for (UINT32 frame = start_frame; frame < m_size; frame++) { // Try to get the source file and line number associated with // this program counter address. SIZE_T programCounter = (*this)[frame]; g_symbolLock.Enter(); BOOL foundline = FALSE; DWORD displacement = 0; DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo); if (foundline && !showInternalFrames) { wcscpy_s(lowerCaseName, sourceInfo.FileName); _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1); if (isInternalModule(lowerCaseName)) { // Don't show frames in files internal to the heap. g_symbolLock.Leave(); continue; } } // Initialize structures passed to the symbol handler. SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer; functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; // Try to get the name of the function containing this program // counter address. DWORD64 displacement64 = 0; LPWSTR functionName; DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) { functionName = functionInfo->Name; } else { // GetFormattedMessage( GetLastError() ); functionName = L"(Function name unavailable)"; displacement64 = 0; } g_symbolLock.Leave(); HMODULE hCallingModule = GetCallingModule(programCounter); LPWSTR moduleName = L"(Module name unavailable)"; if (hCallingModule && GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) { moduleName = wcsrchr(callingModuleName, L'\\'); if (moduleName == NULL) moduleName = wcsrchr(callingModuleName, L'/'); if (moduleName != NULL) moduleName++; else moduleName = callingModuleName; } // Use static here to increase performance, and avoid heap allocs. Hopefully this won't // prove to be an issue in thread safety. If it does, it will have to be simply non-static. static WCHAR stack_line[MAXREPORTLENGTH + 1] = L""; int NumChars = -1; // Display the current stack frame's information. if (foundline) { if (displacement == 0) NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L" %s (%d): %s!%s\n", sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName); else NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L" %s (%d): %s!%s + 0x%X bytes\n", sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement); } else { if (displacement64 == 0) NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L" " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", programCounter, moduleName, functionName); else NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L" " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", programCounter, moduleName, functionName, (DWORD)displacement64); } Print(stack_line); } }
void qtDLGCallstack::ShowCallStack() { clsDebugger *pDebugger = qtDLGNanomite::GetInstance()->coreDebugger; HANDLE hProc = pDebugger->GetCurrentProcessHandle(), hThread = OpenThread(THREAD_GETSET_CONTEXT,false,pDebugger->GetCurrentTID()); PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * 2); DWORD dwMaschineMode = NULL; LPVOID pContext; STACKFRAME64 stackFr = {0}; stackFr.AddrPC.Mode = AddrModeFlat; stackFr.AddrFrame.Mode = AddrModeFlat; stackFr.AddrStack.Mode = AddrModeFlat; QString sFuncName, sFuncMod, sReturnToFunc, sReturnToMod; quint64 dwStackAddr, dwReturnTo, dwEIP, dwDisplacement; IMAGEHLP_LINEW64 imgSource = {0}; IMAGEHLP_MODULEW64 imgMod = {0}; #ifdef _AMD64_ BOOL bIsWOW64 = false; if(clsAPIImport::pIsWow64Process) clsAPIImport::pIsWow64Process(hProc,&bIsWOW64); if(bIsWOW64) { dwMaschineMode = IMAGE_FILE_MACHINE_I386; WOW64_CONTEXT cTT = pDebugger->wowProcessContext; pContext = &cTT; stackFr.AddrPC.Offset = cTT.Eip; stackFr.AddrFrame.Offset = cTT.Ebp; stackFr.AddrStack.Offset = cTT.Esp; } else { dwMaschineMode = IMAGE_FILE_MACHINE_AMD64; CONTEXT cTT = pDebugger->ProcessContext; pContext = &cTT; stackFr.AddrPC.Offset = cTT.Rip; stackFr.AddrFrame.Offset = cTT.Rbp; stackFr.AddrStack.Offset = cTT.Rsp; } #else dwMaschineMode = IMAGE_FILE_MACHINE_I386; CONTEXT cTT = pDebugger->ProcessContext; pContext = &cTT; stackFr.AddrPC.Offset = cTT.Eip; stackFr.AddrFrame.Offset = cTT.Ebp; stackFr.AddrStack.Offset = cTT.Esp; #endif tblCallstack->setRowCount(0); do { if(!StackWalk64(dwMaschineMode,hProc,hThread,&stackFr,pContext,NULL,SymFunctionTableAccess64,SymGetModuleBase64,0)) break; memset(&imgSource,0,sizeof(IMAGEHLP_LINEW64)); imgSource.SizeOfStruct = sizeof(IMAGEHLP_LINEW64); dwStackAddr = stackFr.AddrStack.Offset; dwEIP = stackFr.AddrPC.Offset; dwReturnTo = stackFr.AddrReturn.Offset; memset(&imgMod,0,sizeof(IMAGEHLP_MODULEW64)); imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64); memset(pSymbol,0,sizeof(SYMBOL_INFOW) + MAX_PATH * 2); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW); pSymbol->MaxNameLen = MAX_PATH; SymGetModuleInfoW64(hProc,dwEIP,&imgMod); SymFromAddrW(hProc,dwEIP,&dwDisplacement,pSymbol); sFuncName = QString::fromWCharArray(pSymbol->Name); sFuncMod = QString::fromWCharArray(imgMod.ModuleName); memset(&imgMod,0,sizeof(IMAGEHLP_MODULEW64)); imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64); memset(pSymbol,0,sizeof(SYMBOL_INFOW) + MAX_PATH * 2); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW); pSymbol->MaxNameLen = MAX_PATH; SymGetModuleInfoW64(hProc,dwReturnTo,&imgMod); SymFromAddrW(hProc,dwReturnTo,&dwDisplacement,pSymbol); sReturnToMod = QString::fromWCharArray(imgMod.ModuleName); sReturnToFunc = QString::fromWCharArray(pSymbol->Name); if(SymGetLineFromAddrW64(hProc,dwEIP,(PDWORD)&dwDisplacement,&imgSource)) { OnCallStack(dwStackAddr, dwReturnTo,sReturnToFunc,sReturnToMod, dwEIP,sFuncName,sFuncMod, QString::fromWCharArray(imgSource.FileName),imgSource.LineNumber); } else { OnCallStack(dwStackAddr, dwReturnTo,sReturnToFunc,sReturnToMod, dwEIP,sFuncName,sFuncMod, QString(""),0); } }while(stackFr.AddrReturn.Offset != 0); free(pSymbol); CloseHandle(hThread); }
void clsCallstackWorker::run() { HANDLE hThread = OpenThread(THREAD_GETSET_CONTEXT, false, m_processingData.threadID); PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * 2); DWORD dwMaschineMode = NULL; quint64 dwDisplacement = NULL; LPVOID pContext; QList<callstackDisplay> callstackDisplayData; callstackDisplay newDisplayData = { 0 }; STACKFRAME64 stackFr = { 0 }; IMAGEHLP_LINEW64 imgSource = { 0 }; IMAGEHLP_MODULEW64 imgMod = { 0 }; stackFr.AddrPC.Mode = AddrModeFlat; stackFr.AddrFrame.Mode = AddrModeFlat; stackFr.AddrStack.Mode = AddrModeFlat; #ifdef _AMD64_ if(m_processingData.isWOW64) { dwMaschineMode = IMAGE_FILE_MACHINE_I386; WOW64_CONTEXT cTT = m_processingData.wowProcessContext; pContext = &cTT; stackFr.AddrPC.Offset = cTT.Eip; stackFr.AddrFrame.Offset = cTT.Ebp; stackFr.AddrStack.Offset = cTT.Esp; } else { dwMaschineMode = IMAGE_FILE_MACHINE_AMD64; CONTEXT cTT = m_processingData.processContext; pContext = &cTT; stackFr.AddrPC.Offset = cTT.Rip; stackFr.AddrFrame.Offset = cTT.Rbp; stackFr.AddrStack.Offset = cTT.Rsp; } #else dwMaschineMode = IMAGE_FILE_MACHINE_I386; CONTEXT cTT = m_processingData.processContext; pContext = &cTT; stackFr.AddrPC.Offset = cTT.Eip; stackFr.AddrFrame.Offset = cTT.Ebp; stackFr.AddrStack.Offset = cTT.Esp; #endif do { if(!StackWalk64(dwMaschineMode, m_processingData.processHandle, hThread, &stackFr, pContext, NULL, SymFunctionTableAccess64, SymGetModuleBase64, 0)) break; memset(&imgSource, 0, sizeof(IMAGEHLP_LINEW64)); imgSource.SizeOfStruct = sizeof(IMAGEHLP_LINEW64); newDisplayData.stackAddress = stackFr.AddrStack.Offset; newDisplayData.currentOffset = stackFr.AddrPC.Offset; newDisplayData.returnOffset = stackFr.AddrReturn.Offset; memset(&imgMod, 0, sizeof(IMAGEHLP_MODULEW64)); imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64); memset(pSymbol, 0, sizeof(SYMBOL_INFOW) + MAX_PATH * 2); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW); pSymbol->MaxNameLen = MAX_PATH; SymGetModuleInfoW64(m_processingData.processHandle, newDisplayData.currentOffset, &imgMod); SymFromAddrW(m_processingData.processHandle, newDisplayData.currentOffset, &dwDisplacement, pSymbol); newDisplayData.currentFunctionName = QString::fromWCharArray(pSymbol->Name); newDisplayData.currentModuleName = QString::fromWCharArray(imgMod.ModuleName); memset(&imgMod, 0, sizeof(IMAGEHLP_MODULEW64)); imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64); memset(pSymbol, 0, sizeof(SYMBOL_INFOW) + MAX_PATH * 2); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW); pSymbol->MaxNameLen = MAX_PATH; SymGetModuleInfoW64(m_processingData.processHandle, newDisplayData.returnOffset, &imgMod); SymFromAddrW(m_processingData.processHandle, newDisplayData.returnOffset , &dwDisplacement, pSymbol); newDisplayData.returnModuleName = QString::fromWCharArray(imgMod.ModuleName); newDisplayData.returnFunctionName = QString::fromWCharArray(pSymbol->Name); if(SymGetLineFromAddrW64(m_processingData.processHandle, newDisplayData.currentOffset, (PDWORD)&dwDisplacement, &imgSource)) { newDisplayData.sourceFilePath = QString::fromWCharArray(imgSource.FileName); newDisplayData.sourceLineNumber = imgSource.LineNumber; } else { newDisplayData.sourceFilePath = ""; newDisplayData.sourceLineNumber = 0; } callstackDisplayData.append(newDisplayData); } while(stackFr.AddrReturn.Offset != 0); free(pSymbol); CloseHandle(hThread); emit OnCallstackFinished(callstackDisplayData); }