int CMiniDumpReader::ReadModuleListStream() { LPVOID pStreamStart = NULL; ULONG uStreamSize = 0; MINIDUMP_DIRECTORY* pmd = NULL; BOOL bRead = FALSE; strconv_t strconv; bRead = MiniDumpReadDumpStream( m_pMiniDumpStartPtr, ModuleListStream, &pmd, &pStreamStart, &uStreamSize); if(bRead) { MINIDUMP_MODULE_LIST* pModuleStream = (MINIDUMP_MODULE_LIST*)pStreamStart; if(pModuleStream!=NULL) { ULONG32 uNumberOfModules = pModuleStream->NumberOfModules; ULONG32 i; for(i=0; i<uNumberOfModules; i++) { MINIDUMP_MODULE* pModule = (MINIDUMP_MODULE*)((LPBYTE)pModuleStream->Modules+i*sizeof(MINIDUMP_MODULE)); CString sModuleName = GetMinidumpString(m_pMiniDumpStartPtr, pModule->ModuleNameRva); LPCWSTR szModuleName = strconv.t2w(sModuleName); DWORD64 dwBaseAddr = pModule->BaseOfImage; DWORD64 dwImageSize = pModule->SizeOfImage; CString sShortModuleName = sModuleName; int pos = -1; pos = sModuleName.ReverseFind('\\'); if(pos>=0) sShortModuleName = sShortModuleName.Mid(pos+1); /*DWORD64 dwLoadResult = */SymLoadModuleExW( m_DumpData.m_hProcess, NULL, (PWSTR)szModuleName, NULL, dwBaseAddr, (DWORD)dwImageSize, NULL, 0); IMAGEHLP_MODULE64 modinfo; memset(&modinfo, 0, sizeof(IMAGEHLP_MODULE64)); modinfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); BOOL bModuleInfo = SymGetModuleInfo64(m_DumpData.m_hProcess, dwBaseAddr, &modinfo); MdmpModule m; if(!bModuleInfo) { m.m_bImageUnmatched = TRUE; m.m_bNoSymbolInfo = TRUE; m.m_bPdbUnmatched = TRUE; m.m_pVersionInfo = NULL; m.m_sImageName = sModuleName; m.m_sModuleName = sShortModuleName; m.m_uBaseAddr = dwBaseAddr; m.m_uImageSize = dwImageSize; } else { m.m_uBaseAddr = modinfo.BaseOfImage; m.m_uImageSize = modinfo.ImageSize; m.m_sModuleName = sShortModuleName; m.m_sImageName = modinfo.ImageName; m.m_sLoadedImageName = modinfo.LoadedImageName; m.m_sLoadedPdbName = modinfo.LoadedPdbName; m.m_pVersionInfo = &pModule->VersionInfo; m.m_bPdbUnmatched = modinfo.PdbUnmatched; BOOL bTimeStampMatched = pModule->TimeDateStamp == modinfo.TimeDateStamp; m.m_bImageUnmatched = !bTimeStampMatched; m.m_bNoSymbolInfo = !modinfo.GlobalSymbols; } m_DumpData.m_Modules.push_back(m); m_DumpData.m_ModuleIndex[m.m_uBaseAddr] = m_DumpData.m_Modules.size()-1; CString sMsg; if(m.m_bImageUnmatched) sMsg.Format(_T("Loaded '*%s'"), sModuleName); else sMsg.Format(_T("Loaded '%s'"), m.m_sLoadedImageName); if(m.m_bImageUnmatched) sMsg += _T(", No matching binary found."); else if(m.m_bPdbUnmatched) sMsg += _T(", No matching PDB file found."); else { if(m.m_bNoSymbolInfo) sMsg += _T(", No symbols loaded."); else sMsg += _T(", Symbols loaded."); } m_DumpData.m_LoadLog.push_back(sMsg); } } } else { return 1; } return 0; }
/****************************************************************** * break_delete_xpoints_from_module * * Remove all Xpoints from module which base is 'base' */ void break_delete_xpoints_from_module(DWORD64 base) { IMAGEHLP_MODULE64 im, im_elf; int i; DWORD_PTR linear; struct dbg_breakpoint* bp = dbg_curr_process->bp; /* FIXME: should do it also on the ELF sibling if any */ im.SizeOfStruct = sizeof(im); im_elf.SizeOfStruct = sizeof(im_elf); if (!SymGetModuleInfo64(dbg_curr_process->handle, base, &im)) return; /* try to get in fact the underlying ELF module (if any) */ if (SymGetModuleInfo64(dbg_curr_process->handle, im.BaseOfImage - 1, &im_elf) && im_elf.BaseOfImage <= im.BaseOfImage && im_elf.BaseOfImage + im_elf.ImageSize >= im.BaseOfImage + im.ImageSize) im = im_elf; for (i = 0; i < dbg_curr_process->next_bp; i++) { if (bp[i].refcount && bp[i].enabled) { linear = (DWORD_PTR)memory_to_linear_addr(&bp[i].addr); if (im.BaseOfImage <= linear && linear < im.BaseOfImage + im.ImageSize) { break_delete_xpoint(i); } } } }
std::string format_address_win32(const void* addr) const { if (!dbghelp.initialized()) return format_address_fallback(addr); DWORD64 symbol_info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; const auto symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buf); symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); symbol_info->MaxNameLen = MAX_SYM_NAME; IMAGEHLP_MODULE64 module_info; module_info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); DWORD64 symbol_offset; const auto symbol_resolved = SymFromAddr( GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &symbol_offset, symbol_info); if (symbol_resolved) { const auto module_resolved = SymGetModuleInfo64( GetCurrentProcess(), symbol_info->ModBase, &module_info); if (module_resolved) { return format_symbol( module_info.ModuleName, symbol_info->Name, reinterpret_cast<const void*>(symbol_offset)); } else { return format_symbol(symbol_info->Name, addr); } } else { const auto module_resolved = SymGetModuleInfo64( GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &module_info); if (module_resolved) { const auto module_offset = reinterpret_cast<const char*>(addr) - module_info.BaseOfImage; return format_module(module_info.ModuleName, module_offset); } else { return format_address_fallback(addr); } } }
bool CSymbolEngine::GetModuleInfo( DWORD64 Addr, IMAGEHLP_MODULE64& Info ) { // Check preconditions if( m_hProcess == NULL ) { _ASSERTE( !_T("Symbol engine is not yet initialized.") ); m_LastError = ERROR_INVALID_FUNCTION; return false; } // Obtain module information memset( &Info, 0, sizeof(Info) ); Info.SizeOfStruct = sizeof(Info); if( !SymGetModuleInfo64( m_hProcess, Addr, &Info ) ) { m_LastError = GetLastError(); _ASSERTE( !_T("SymGetModuleInfo64() failed.") ); return false; } return true; }
void GetSourceFileInfo(DWORD64 dw64Address, FILE * fw) { IMAGEHLP_LINE64 il64LineInfo; memset(&il64LineInfo, 0, sizeof(IMAGEHLP_LINE64)); il64LineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); DWORD dwDisplacement = 0; if(SymGetLineFromAddr64(GetCurrentProcess(), dw64Address, &dwDisplacement, &il64LineInfo) == TRUE) { // We have sourcefile and linenumber info, write it. fprintf(fw, "%s(%d): ", il64LineInfo.FileName, il64LineInfo.LineNumber); } else { // We don't have sourcefile and linenumber info, let's try module name IMAGEHLP_MODULE64 im64ModuleInfo; memset(&im64ModuleInfo, 0, sizeof(IMAGEHLP_MODULE64)); im64ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); if(SymGetModuleInfo64(GetCurrentProcess(), dw64Address, &im64ModuleInfo)) { // We found module name, write module name and address fprintf(fw, "%s|0x%08I64X: ", im64ModuleInfo.ModuleName, dw64Address); } else { // We don't found module. Write address, it's better than nothing fprintf(fw, "0x%08I64X: ", dw64Address); } } }
static BOOL CALLBACK mod_loader_cb(PCSTR mod_name, DWORD64 base, PVOID ctx) { struct mod_loader_info* mli = ctx; if (!strcmp(mod_name, "<wine-loader>")) { if (SymGetModuleInfo64(mli->handle, base, mli->imh_mod)) return FALSE; /* stop enum */ } return TRUE; }
void PlatformStack::ProgramAddressToSymbolInfo(uint64 address, SymbolInfo& oSymbolInfo) { InitSysStack(); oSymbolInfo.Address = address; uint32 lastError = 0; HANDLE processHandle = GetCurrentProcess(); ansichar symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + SymbolInfo::MAX_NAME_LENGHT] = { 0 }; IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)symbolBuffer; symbol->SizeOfStruct = sizeof(symbolBuffer); symbol->MaxNameLength = SymbolInfo::MAX_NAME_LENGHT; if (SymGetSymFromAddr64(processHandle, address, nullptr, symbol)) { int32 offset = 0; while (symbol->Name[offset] < 32 || symbol->Name[offset] > 127) { offset++; } strncpy(oSymbolInfo.FunctionName, symbol->Name + offset, SymbolInfo::MAX_NAME_LENGHT); strncat(oSymbolInfo.FunctionName, "()", SymbolInfo::MAX_NAME_LENGHT); } else { lastError = GetLastError(); } IMAGEHLP_LINE64 imageHelpLine = { 0 }; imageHelpLine.SizeOfStruct = sizeof(imageHelpLine); if (SymGetLineFromAddr64(processHandle, address, (::DWORD *)&oSymbolInfo.SymbolDisplacement, &imageHelpLine)) { strncpy(oSymbolInfo.FileName, imageHelpLine.FileName, SymbolInfo::MAX_NAME_LENGHT); oSymbolInfo.LineNumber = imageHelpLine.LineNumber; } else { lastError = GetLastError(); } IMAGEHLP_MODULE64 imageHelpModule = { 0 }; imageHelpModule.SizeOfStruct = sizeof(imageHelpModule); if (SymGetModuleInfo64(processHandle, address, &imageHelpModule)) { strncpy(oSymbolInfo.ModuleName, imageHelpModule.ImageName, SymbolInfo::MAX_NAME_LENGHT); } else { lastError = GetLastError(); } }
QString AbstractBTGenerator::GetModulePath() { IMAGEHLP_MODULE64 module; ZeroMemory(&module, sizeof(module)); module.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); if (!SymGetModuleInfo64(m_process.GetHandle(), m_currentFrame.AddrPC.Offset, &module)) { qCritical() << "SymGetModuleInfo64 failed: " << GetLastError(); return QLatin1String(DEFAULT_MODULE); } return QString(module.ImageName); }
void CDebugger::PrintCallStack(DWORD dwThreadId, DWORD dwProcessId) { STACKFRAME64 stackFrame = { 0 }; const DWORD_PTR dwMaxFrames = 50; UpdateContext(dwThreadId); stackFrame.AddrPC.Mode = AddrModeFlat; stackFrame.AddrFrame.Mode = AddrModeFlat; stackFrame.AddrStack.Mode = AddrModeFlat; DWORD dwMachineType = IMAGE_FILE_MACHINE_I386; stackFrame.AddrPC.Offset = m_context.Eip; stackFrame.AddrFrame.Offset = m_context.Ebp; stackFrame.AddrStack.Offset = m_context.Esp; HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, dwThreadId); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); m_pSymbols->RefreshSymbols(hProcess); // Print call stack stringstream ssCallStack; for (int i = 0; i < dwMaxFrames; ++i) { bool bSuccess = StackWalk64(dwMachineType, hProcess, hThread, &stackFrame, (dwMachineType == IMAGE_FILE_MACHINE_I386 ? nullptr : &m_context), nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr); if (!bSuccess || stackFrame.AddrPC.Offset == 0) { cout << "StackWalk64 finished." << endl; break; } IMAGEHLP_MODULE64 module = {0}; module.SizeOfStruct = sizeof(module); SymGetModuleInfo64(hProcess, (DWORD64)stackFrame.AddrPC.Offset, &module); //SymLoadModuleEx(hProcess, NULL, module.LoadedImageName, NULL, module.BaseOfImage, 0, NULL, 0); //cout << "modulePath: " << module.LoadedImageName << ", baseofdll: " << module.BaseOfImage << ", symbol: " << module.LoadedPdbName << endl; PSYMBOL_INFO pSymInfo = m_pSymbols->SymbolFromAddress(stackFrame.AddrPC.Offset); if (pSymInfo) { ssCallStack << "#" << dec << i << " " << module.ModuleName << "!" << pSymInfo->Name << endl; } else { ssCallStack << "#" << dec << i << " " << module.ModuleName << "!" << "unknown" << endl; } delete pSymInfo; } m_pCrash->GetHash(ssCallStack.str()); m_pCrash->AddLog("\nCall Stack\n" + ssCallStack.str()); }
char *Pobjname(struct ps_prochandle *P, uintptr_t addr, char *buffer, size_t bufsize) { IMAGEHLP_MODULE64 info; info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); if (SymGetModuleInfo64(P->phandle, (DWORD64) addr, &info) == FALSE) { dprintf("SymGetModuleInfo64 failed (%d): %x\n", P->pid, GetLastError()); buffer[0] = 0; return NULL; } strncpy(buffer, info.ModuleName, bufsize); buffer[bufsize-1] = 0; return buffer; }
/** * Get the display name of the executable module containing the specified address. * * @param process Process handle * @param address Address to find * @param returnedModuleName Returned module name */ static void getModuleName( HANDLE process, DWORD64 address, std::string* returnedModuleName ) { IMAGEHLP_MODULE64 module64; memset ( &module64, 0, sizeof(module64) ); module64.SizeOfStruct = sizeof(module64); BOOL ret = SymGetModuleInfo64( process, address, &module64 ); if ( FALSE == ret ) { returnedModuleName->clear(); return; } char* moduleName = module64.LoadedImageName; char* backslash = strrchr( moduleName, '\\' ); if ( backslash ) { moduleName = backslash + 1; } *returnedModuleName = moduleName; }
QString org_blueberry_core_runtime_Activator::getPluginId(void *symbol) { if (symbol == NULL) return QString(); if (ctk::DebugSymInitialize()) { std::vector<char> moduleBuffer(sizeof(IMAGEHLP_MODULE64)); PIMAGEHLP_MODULE64 pModuleInfo = (PIMAGEHLP_MODULE64)&moduleBuffer.front(); pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64); if (SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)symbol, pModuleInfo)) { QString pluginId = pModuleInfo->ModuleName; return pluginId.replace('_', '.'); } } return QString(); }
/****************************************************************** * SymGetModuleInfoW64 (DBGHELP.@) * */ BOOL WINAPI SymGetModuleInfoW64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULEW64 ModuleInfo) { IMAGEHLP_MODULE64 mi; IMAGEHLP_MODULEW64 miw; if (sizeof(miw) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n"); mi.SizeOfStruct = sizeof(mi); if (!SymGetModuleInfo64(hProcess, dwAddr, &mi)) return FALSE; miw.SizeOfStruct = mi.SizeOfStruct; miw.BaseOfImage = mi.BaseOfImage; miw.ImageSize = mi.ImageSize; miw.TimeDateStamp = mi.TimeDateStamp; miw.CheckSum = mi.CheckSum; miw.NumSyms = mi.NumSyms; miw.SymType = mi.SymType; MultiByteToWideChar(CP_ACP, 0, mi.ModuleName, -1, miw.ModuleName, sizeof(miw.ModuleName) / sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, mi.ImageName, -1, miw.ImageName, sizeof(miw.ImageName) / sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, mi.LoadedImageName, -1, miw.LoadedImageName, sizeof(miw.LoadedImageName) / sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, mi.LoadedPdbName, -1, miw.LoadedPdbName, sizeof(miw.LoadedPdbName) / sizeof(WCHAR)); miw.CVSig = mi.CVSig; MultiByteToWideChar(CP_ACP, 0, mi.CVData, -1, miw.CVData, sizeof(miw.CVData) / sizeof(WCHAR)); miw.PdbSig = mi.PdbSig; miw.PdbSig70 = mi.PdbSig70; miw.PdbAge = mi.PdbAge; miw.PdbUnmatched = mi.PdbUnmatched; miw.DbgUnmatched = mi.DbgUnmatched; miw.LineNumbers = mi.LineNumbers; miw.GlobalSymbols = mi.GlobalSymbols; miw.TypeInfo = mi.TypeInfo; miw.SourceIndexed = mi.SourceIndexed; miw.Publics = mi.Publics; memcpy(ModuleInfo, &miw, ModuleInfo->SizeOfStruct); return TRUE; }
// -------------------------------------------------------------------------- std::string ctkBackTracePrivate::getSymbol(void* ptr) const { if(ptr==0) return std::string(); ctk::DebugSymInitialize(); std::ostringstream ss; ss.imbue(std::locale::classic()); ss << ptr; if(syms_ready) { DWORD64 dwDisplacement = 0; DWORD64 dwAddress = (DWORD64)ptr; std::vector<char> buffer(sizeof(SYMBOL_INFO) + MAX_SYM_NAME); PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)&buffer.front(); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; if (SymFromAddr(hProcess, dwAddress, &dwDisplacement, pSymbol)) { ss <<": " << pSymbol->Name << std::hex << " + 0x" << dwDisplacement; } else { ss << ": ???"; } std::vector<char> moduleBuffer(sizeof(IMAGEHLP_MODULE64)); PIMAGEHLP_MODULE64 pModuleInfo = (PIMAGEHLP_MODULE64)&moduleBuffer.front(); pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64); if (SymGetModuleInfo64(hProcess, pSymbol->ModBase, pModuleInfo)) { ss << " in " << pModuleInfo->LoadedImageName; } } return ss.str(); }
/* * Find Symbol in symbol table * To use this, this source must be compiled in debug mode. * No solution without /DEBUG option yet. */ ACP_EXPORT acp_rc_t acpSymFind(acp_sym_table_t *aSymTable, acp_sym_info_t *aSymInfo, void *aAddr) { IMAGEHLP_MODULE64 *sModule = &aSymTable->mModule; SYMBOL_INFO *sSymbol = (SYMBOL_INFO *)aSymTable->mSymbolBuffer; BOOL sRet; sRet = SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)aAddr, sModule); if (sRet == 0) { acpStrSetConstCString(&aSymInfo->mFileName, NULL); aSymInfo->mFileAddr = NULL; } else { acpStrSetConstCString(&aSymInfo->mFileName, sModule->LoadedImageName); aSymInfo->mFileAddr = (void *)(acp_ulong_t)sModule->BaseOfImage; } sRet = SymFromAddr(GetCurrentProcess(), (DWORD64)aAddr, NULL, sSymbol); if (sRet == 0) { acpStrSetConstCString(&aSymInfo->mFuncName, NULL); aSymInfo->mFuncAddr = NULL; } else { acpStrSetConstCString(&aSymInfo->mFuncName, sSymbol->Name); aSymInfo->mFuncAddr = (void *)(acp_ulong_t)sSymbol->Address; } return ACP_RC_SUCCESS; }
PRAGMA_ENABLE_OPTIMIZATION void FWindowsPlatformStackWalk::ProgramCounterToSymbolInfo( uint64 ProgramCounter, FProgramCounterSymbolInfo& out_SymbolInfo ) { // Initialize stack walking as it loads up symbol information which we require. InitStackWalking(); // Set the program counter. out_SymbolInfo.ProgramCounter = ProgramCounter; uint32 LastError = 0; HANDLE ProcessHandle = GetCurrentProcess(); // Initialize symbol. ANSICHAR SymbolBuffer[sizeof( IMAGEHLP_SYMBOL64 ) + FProgramCounterSymbolInfo::MAX_NAME_LENGHT] = {0}; IMAGEHLP_SYMBOL64* Symbol = (IMAGEHLP_SYMBOL64*)SymbolBuffer; Symbol->SizeOfStruct = sizeof(SymbolBuffer); Symbol->MaxNameLength = FProgramCounterSymbolInfo::MAX_NAME_LENGHT; // Get function name. if( SymGetSymFromAddr64( ProcessHandle, ProgramCounter, nullptr, Symbol ) ) { // Skip any funky chars in the beginning of a function name. int32 Offset = 0; while( Symbol->Name[Offset] < 32 || Symbol->Name[Offset] > 127 ) { Offset++; } // Write out function name. FCStringAnsi::Strncpy( out_SymbolInfo.FunctionName, Symbol->Name + Offset, FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); FCStringAnsi::Strncat( out_SymbolInfo.FunctionName, "()", FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); } else { // No symbol found for this address. LastError = GetLastError(); } // Get filename and line number. IMAGEHLP_LINE64 ImageHelpLine = {0}; ImageHelpLine.SizeOfStruct = sizeof( ImageHelpLine ); if( SymGetLineFromAddr64( ProcessHandle, ProgramCounter, (::DWORD *)&out_SymbolInfo.SymbolDisplacement, &ImageHelpLine ) ) { FCStringAnsi::Strncpy( out_SymbolInfo.Filename, ImageHelpLine.FileName, FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); out_SymbolInfo.LineNumber = ImageHelpLine.LineNumber; } else { LastError = GetLastError(); } // Get module name. IMAGEHLP_MODULE64 ImageHelpModule = {0}; ImageHelpModule.SizeOfStruct = sizeof( ImageHelpModule ); if( SymGetModuleInfo64( ProcessHandle, ProgramCounter, &ImageHelpModule) ) { // Write out module information. FCStringAnsi::Strncpy( out_SymbolInfo.ModuleName, ImageHelpModule.ImageName, FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); } else { LastError = GetLastError(); } }
void printStackTrace( std::ostream &os ) { HANDLE process = GetCurrentProcess(); BOOL ret = SymInitialize( process, NULL, TRUE ); if ( ret == FALSE ) { DWORD dosError = GetLastError(); os << "Stack trace failed, SymInitialize failed with error " << std::dec << dosError << std::endl; return; } DWORD options = SymGetOptions(); options |= SYMOPT_LOAD_LINES | SYMOPT_FAIL_CRITICAL_ERRORS; SymSetOptions( options ); CONTEXT context; memset( &context, 0, sizeof(context) ); context.ContextFlags = CONTEXT_CONTROL; RtlCaptureContext( &context ); STACKFRAME64 frame64; memset( &frame64, 0, sizeof(frame64) ); #if defined(_M_AMD64) DWORD imageType = IMAGE_FILE_MACHINE_AMD64; frame64.AddrPC.Offset = context.Rip; frame64.AddrFrame.Offset = context.Rbp; frame64.AddrStack.Offset = context.Rsp; #elif defined(_M_IX86) DWORD imageType = IMAGE_FILE_MACHINE_I386; frame64.AddrPC.Offset = context.Eip; frame64.AddrFrame.Offset = context.Ebp; frame64.AddrStack.Offset = context.Esp; #else #error Neither _M_IX86 nor _M_AMD64 were defined #endif frame64.AddrPC.Mode = AddrModeFlat; frame64.AddrFrame.Mode = AddrModeFlat; frame64.AddrStack.Mode = AddrModeFlat; const size_t nameSize = 1024; const size_t symbolRecordSize = sizeof(SYMBOL_INFO) + nameSize; boost::scoped_array<char> symbolBuffer( new char[symbolRecordSize] ); memset( symbolBuffer.get(), 0, symbolRecordSize ); SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>( symbolBuffer.get() ); symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = nameSize; std::vector<TraceItem> traceList; TraceItem traceItem; size_t moduleWidth = 0; size_t fileWidth = 0; size_t frameCount = 0; for ( size_t i = 0; i < maxBackTraceFrames; ++i ) { ret = StackWalk64( imageType, process, GetCurrentThread(), &frame64, &context, NULL, NULL, NULL, NULL ); if ( ret == FALSE || frame64.AddrReturn.Offset == 0 ) { frameCount = i; break; } // module (executable) name IMAGEHLP_MODULE64 module; memset ( &module, 0, sizeof(module) ); module.SizeOfStruct = sizeof(module); ret = SymGetModuleInfo64( process, frame64.AddrPC.Offset, &module ); char* moduleName = module.LoadedImageName; char* backslash = strrchr( moduleName, '\\' ); if ( backslash ) { moduleName = backslash + 1; } traceItem.module = moduleName; size_t len = traceItem.module.length(); if ( len > moduleWidth ) { moduleWidth = len; } // source code filename and line number IMAGEHLP_LINE64 line; memset( &line, 0, sizeof(line) ); line.SizeOfStruct = sizeof(line); DWORD displacement32; ret = SymGetLineFromAddr64( process, frame64.AddrPC.Offset, &displacement32, &line ); if ( ret ) { std::string filename( line.FileName ); std::string::size_type start = filename.find( "\\src\\mongo\\" ); if ( start == std::string::npos ) { start = filename.find( "\\src\\third_party\\" ); } if ( start != std::string::npos ) { std::string shorter( "..." ); shorter += filename.substr( start ); traceItem.sourceFile.swap( shorter ); } else { traceItem.sourceFile.swap( filename ); } len = traceItem.sourceFile.length() + 3; traceItem.lineNumber = line.LineNumber; if ( traceItem.lineNumber < 10 ) { len += 1; } else if ( traceItem.lineNumber < 100 ) { len += 2; } else if ( traceItem.lineNumber < 1000 ) { len += 3; } else if ( traceItem.lineNumber < 10000 ) { len += 4; } else { len += 5; } traceItem.sourceLength = len; if ( len > fileWidth ) { fileWidth = len; } } else { traceItem.sourceFile.clear(); traceItem.sourceLength = 0; } // symbol name and offset from symbol DWORD64 displacement; ret = SymFromAddr( process, frame64.AddrPC.Offset, &displacement, symbol ); if ( ret ) { traceItem.symbol = symbol->Name; traceItem.instructionOffset = displacement; } else { traceItem.symbol = "???"; traceItem.instructionOffset = 0; } // add to list traceList.push_back( traceItem ); } SymCleanup( process ); // print list ++moduleWidth; ++fileWidth; for ( size_t i = 0; i < frameCount; ++i ) { os << traceList[i].module << " "; size_t width = traceList[i].module.length(); while ( width < moduleWidth ) { os << " "; ++width; } if ( traceList[i].sourceFile.length() ) { os << traceList[i].sourceFile << "(" << std::dec << traceList[i].lineNumber << ") "; } width = traceList[i].sourceLength; while ( width < fileWidth ) { os << " "; ++width; } os << traceList[i].symbol << "+0x" << std::hex << traceList[i].instructionOffset; os << std::endl; } }
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC) { #ifdef _OS_WINDOWS_ DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer); char *fname = 0; if (fbase != 0) { #else Dl_info dlinfo; const char *fname = 0; if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) { *fromC = !jl_is_sysimg(dlinfo.dli_fname); if (skipC && *fromC) return; // In case we fail with the debug info lookup, we at least still // have the function name, even if we don't have line numbers *name = dlinfo.dli_sname; *filename = dlinfo.dli_fname; uint64_t fbase = (uint64_t)dlinfo.dli_fbase; #endif obfiletype::iterator it = objfilemap.find(fbase); llvm::object::ObjectFile *obj = NULL; DIContext *context = NULL; int64_t slide = 0; #ifndef _OS_WINDOWS_ fname = dlinfo.dli_fname; #else IMAGEHLP_MODULE64 ModuleInfo; ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo); fname = ModuleInfo.LoadedImageName; *fromC = !jl_is_sysimg(fname); if (skipC && *fromC) return; #endif if (it == objfilemap.end()) { #ifdef _OS_DARWIN_ // First find the uuid of the object file (we'll use this to make sure we find the // correct debug symbol file). uint8_t uuid[16], uuid2[16]; #ifdef LLVM36 std::unique_ptr<MemoryBuffer> membuf = MemoryBuffer::getMemBuffer( StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false); auto origerrorobj = llvm::object::ObjectFile::createObjectFile( membuf->getMemBufferRef(), sys::fs::file_magic::unknown); #elif LLVM35 MemoryBuffer *membuf = MemoryBuffer::getMemBuffer( StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false); std::unique_ptr<MemoryBuffer> buf(membuf); auto origerrorobj = llvm::object::ObjectFile::createObjectFile( buf, sys::fs::file_magic::unknown); #else MemoryBuffer *membuf = MemoryBuffer::getMemBuffer( StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false); llvm::object::ObjectFile *origerrorobj = llvm::object::ObjectFile::createObjectFile( membuf); #endif if (!origerrorobj) { objfileentry_t entry = {obj,context,slide}; objfilemap[fbase] = entry; goto lookup; } #ifdef LLVM36 llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get().release(); #elif LLVM35 llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get(); #else llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj; #endif if (!getObjUUID(morigobj,uuid)) { objfileentry_t entry = {obj,context,slide}; objfilemap[fbase] = entry; goto lookup; } // On OS X debug symbols are not contained in the dynamic library and that's why // we can't have nice things (easily). For now we only support .dSYM files in the same directory // as the shared library. In the future we may use DBGCopyFullDSYMURLForUUID from CoreFoundation to make // use of spotlight to find the .dSYM file. char dsympath[PATH_MAX]; strlcpy(dsympath, dlinfo.dli_fname, sizeof(dsympath)); strlcat(dsympath, ".dSYM/Contents/Resources/DWARF/", sizeof(dsympath)); strlcat(dsympath, strrchr(dlinfo.dli_fname,'/')+1, sizeof(dsympath)); #ifdef LLVM35 auto errorobj = llvm::object::ObjectFile::createObjectFile(dsympath); #else llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(dsympath); #endif #else // On non OS X systems we need to mmap another copy because of the permissions on the mmaped // shared library. #ifdef LLVM35 auto errorobj = llvm::object::ObjectFile::createObjectFile(fname); #else llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(fname); #endif #endif #ifdef LLVM36 if (errorobj) { obj = errorobj.get().getBinary().release(); errorobj.get().getBuffer().release(); #elif LLVM35 if (errorobj) { obj = errorobj.get(); #else if (errorobj != NULL) { obj = errorobj; #endif #ifdef _OS_DARWIN_ if (getObjUUID(morigobj,uuid2) && memcmp(uuid,uuid2,sizeof(uuid)) == 0) { #endif #ifdef LLVM36 context = DIContext::getDWARFContext(*obj); #else context = DIContext::getDWARFContext(obj); #endif slide = -(uint64_t)fbase; #ifdef _OS_DARWIN_ } #endif #ifdef _OS_WINDOWS_ assert(obj->isCOFF()); llvm::object::COFFObjectFile *coffobj = (llvm::object::COFFObjectFile *)obj; const llvm::object::pe32plus_header *pe32plus; coffobj->getPE32PlusHeader(pe32plus); if (pe32plus != NULL) { slide = pe32plus->ImageBase-fbase; } else { const llvm::object::pe32_header *pe32; coffobj->getPE32Header(pe32); if (pe32 == NULL) { obj = NULL; context = NULL; } else { slide = pe32->ImageBase-fbase; } } #endif } objfileentry_t entry = {obj,context,slide}; objfilemap[fbase] = entry; } else { obj = it->second.obj; context = it->second.ctx; slide = it->second.slide; } #ifdef _OS_DARWIN_ lookup: #endif lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(fname), fromC); return; } *fromC = 1; return; } #endif void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC) { *name = NULL; *line = -1; *filename = "no file"; *fromC = 0; #if USE_MCJIT // With MCJIT we can get function information directly from the ObjectFile std::map<size_t, ObjectInfo, revcomp> &objmap = jl_jit_events->getObjectMap(); std::map<size_t, ObjectInfo, revcomp>::iterator it = objmap.lower_bound(pointer); if (it == objmap.end()) return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC); if ((pointer - it->first) > it->second.size) return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC); #ifdef LLVM36 DIContext *context = DIContext::getDWARFContext(*it->second.object); #else DIContext *context = DIContext::getDWARFContext(it->second.object); #endif lookup_pointer(context, name, line, filename, pointer, 1, fromC); #else // !USE_MCJIT // Without MCJIT we use the FuncInfo structure containing address maps std::map<size_t, FuncInfo, revcomp> &info = jl_jit_events->getMap(); std::map<size_t, FuncInfo, revcomp>::iterator it = info.lower_bound(pointer); if (it != info.end() && (size_t)(*it).first + (*it).second.lengthAdr >= pointer) { // We do this to hide the jlcall wrappers when getting julia backtraces, // but it is still good to have them for regular lookup of C frames. if (skipC && (*it).second.lines.empty()) { // Technically not true, but we don't want them // in julia backtraces, so close enough *fromC = 1; return; } *name = (*it).second.name.c_str(); *filename = (*it).second.filename.c_str(); if ((*it).second.lines.empty()) { *fromC = 1; return; } std::vector<JITEvent_EmittedFunctionDetails::LineStart>::iterator vit = (*it).second.lines.begin(); JITEvent_EmittedFunctionDetails::LineStart prev = *vit; if ((*it).second.func) { DISubprogram debugscope = DISubprogram(prev.Loc.getScope((*it).second.func->getContext())); *filename = debugscope.getFilename().data(); // the DISubprogram has the un-mangled name, so use that if // available. However, if the scope need not be the current // subprogram. if (debugscope.getName().data() != NULL) *name = debugscope.getName().data(); else *name = jl_demangle(*name); } vit++; while (vit != (*it).second.lines.end()) { if (pointer <= (*vit).Address) { *line = prev.Loc.getLine(); break; } prev = *vit; vit++; } if (*line == (size_t) -1) { *line = prev.Loc.getLine(); } } else { jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC); } #endif // USE_MCJIT }
void PrintCallStack(const CONTEXT *pContext) { HANDLE hProcess = GetCurrentProcess(); SymInitialize(hProcess, NULL, TRUE); CONTEXT c = *pContext; STACKFRAME64 sf; memset(&sf, 0, sizeof(STACKFRAME64)); DWORD dwImageType = IMAGE_FILE_MACHINE_I386; #ifdef _M_IX86 sf.AddrPC.Offset = c.Eip; sf.AddrPC.Mode = AddrModeFlat; sf.AddrStack.Offset = c.Esp; sf.AddrStack.Mode = AddrModeFlat; sf.AddrFrame.Offset = c.Ebp; sf.AddrFrame.Mode = AddrModeFlat; #elif _M_X64 dwImageType = 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; #elif _M_IA64 dwImageType = 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; #else #error "Platform not supported!" #endif HANDLE hThread = GetCurrentThread(); while (true) { if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; DWORD64 address = sf.AddrPC.Offset; if (address == 0) break; // Get symbol name char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] = {0}; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->MaxNameLen = MAX_SYM_NAME ; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); SymFromAddr(hProcess, address, NULL, pSymbol); // Get module name IMAGEHLP_MODULE64 moduleInfo = {0}; moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); TCHAR* szModule = _T(""); // SymGetModuleInfo64 will fail in unicode version // http://msdn.microsoft.com/en-us/library/windows/desktop/ms681336(v=vs.85).aspx if (SymGetModuleInfo64(hProcess, address, &moduleInfo)) szModule = moduleInfo.ModuleName; // Get file name and line count IMAGEHLP_LINE64 lineInfo = {0}; lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); DWORD displacement; if (SymGetLineFromAddr64(hProcess, address, &displacement, &lineInfo)) { _tprintf(_T("%016llX %s!%s [%s @ %lu]\n"), pSymbol->Address, szModule, pSymbol->Name, lineInfo.FileName, lineInfo.LineNumber); } else { _tprintf(_T("%016llX %s!%s\n"), pSymbol->Address, szModule, pSymbol->Name); } } SymCleanup(hProcess); }
std::vector<std::string> backtrace_get(int skip) { unsigned int i; void * stack[ 100 ]; unsigned short frames; SYMBOL_INFO * symbol; HANDLE process; IMAGEHLP_LINE *line = (IMAGEHLP_LINE *)malloc(sizeof(IMAGEHLP_LINE)); line->SizeOfStruct = sizeof(IMAGEHLP_LINE); IMAGEHLP_LINE64 *line64 = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64)); line64->SizeOfStruct = sizeof(IMAGEHLP_LINE64); IMAGEHLP_MODULE *mod = (IMAGEHLP_MODULE *)malloc(sizeof(IMAGEHLP_MODULE)); mod->SizeOfStruct = sizeof(IMAGEHLP_MODULE); IMAGEHLP_MODULE64 *mod64 = (IMAGEHLP_MODULE64 *)malloc(sizeof(IMAGEHLP_MODULE64)); mod->SizeOfStruct = sizeof(IMAGEHLP_MODULE64); process = GetCurrentProcess(); SymSetOptions(SYMOPT_LOAD_LINES); SymInitialize( process, NULL, TRUE ); frames = CaptureStackBackTrace( 0, 100, stack, NULL ); symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 ); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof( SYMBOL_INFO ); char *buf = (char *)malloc(1024); std::vector<std::string> vs; for( i = skip; i < frames; i++ ){ SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol ); bool m64 = false; BOOL mod_status = SymGetModuleInfo(process, symbol->Address, mod); if (!mod_status) { mod_status = SymGetModuleInfo64(process, symbol->Address, mod64); m64 = true; } DWORD dwDisplacement; bool l64 = false; BOOL line_status = SymGetLineFromAddr(process, (ULONG64)stack[i], &dwDisplacement, line); if (!line_status) { line_status = SymGetLineFromAddr64(process, (ULONG64)stack[i], &dwDisplacement, line64); l64 = true; } sprintf(buf, "%-3d %*p %s(%s + 0x%I64x)", frames - i - 1, int(2 + sizeof(void*) * 2), stack[i], mod_status ? (m64 ? mod64->ModuleName : mod->ModuleName) : "<unknown dll>", symbol->Name, symbol->Address); vs.push_back(std::string(buf)); if (line_status) { sprintf(buf, "\t\t%s:%d", l64 ? line64->FileName : line->FileName, l64 ? line64->LineNumber : line->LineNumber); vs.push_back(std::string(buf)); } } free(buf); free(symbol); SymCleanup(process); return vs; }
int StackTrace::GetSymbolInfo(Address address, char* symbol, int maxSymbolLen) { if (!InitSymbols()) return 0; // Start with address. int charsAdded = _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, "%p ", address); symbol += charsAdded; maxSymbolLen -= charsAdded; if (maxSymbolLen < 0) return charsAdded; const DWORD64 address64 = (DWORD64)address; // Module name IMAGEHLP_MODULE64 moduleInfo; ZeroMemory(&moduleInfo, sizeof(moduleInfo)); moduleInfo.SizeOfStruct = sizeof(moduleInfo); const HANDLE hCurrentProcess = GetCurrentProcess(); if (SymGetModuleInfo64(hCurrentProcess, address64, &moduleInfo)) { char moduleName[_MAX_PATH + 1]; GetFileFromPath(moduleInfo.ImageName, moduleName, _MAX_PATH); const int moduleLen = (int)strlen(moduleName); strncpy_s(symbol, maxSymbolLen, moduleName, _TRUNCATE); symbol += moduleLen; charsAdded += moduleLen; maxSymbolLen -= moduleLen; } if (maxSymbolLen <= 0) return charsAdded; // Symbol name ULONG64 symbolBuffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)] = { 0 }; IMAGEHLP_SYMBOL64* symbolInfo = reinterpret_cast<IMAGEHLP_SYMBOL64*>(symbolBuffer); symbolInfo->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); symbolInfo->MaxNameLength = MAX_SYM_NAME; DWORD64 disp(0); if (SymGetSymFromAddr64(hCurrentProcess, address64, &disp, symbolInfo)) { const int symbolChars = _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, " %s + 0x%X", symbolInfo->Name, disp); symbol += symbolChars; maxSymbolLen -= symbolChars; charsAdded += symbolChars; } if (maxSymbolLen <= 0) return charsAdded; // File + line DWORD displacementLine; IMAGEHLP_LINE64 lineInfo; ZeroMemory(&lineInfo, sizeof(lineInfo)); lineInfo.SizeOfStruct = sizeof(lineInfo); if (SymGetLineFromAddr64(hCurrentProcess, address64, &displacementLine, &lineInfo)) { char fileName[_MAX_PATH + 1]; GetFileFromPath(lineInfo.FileName, fileName, _MAX_PATH); int fileLineChars(0); if (displacementLine > 0) { fileLineChars = _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, " %s(%d+%04d byte(s))", fileName, lineInfo.LineNumber, displacementLine); } else { fileLineChars = _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, " %s(%d)", fileName, lineInfo.LineNumber); } symbol += fileLineChars; maxSymbolLen -= fileLineChars; charsAdded += fileLineChars; } return charsAdded; }
//----------------------------------------------------------------------------// static void dumpBacktrace(size_t frames) { #if defined(_DEBUG) || defined(DEBUG) #if defined(_MSC_VER) SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES); if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) return; HANDLE thread = GetCurrentThread(); CONTEXT context; RtlCaptureContext(&context); STACKFRAME64 stackframe; ZeroMemory(&stackframe, sizeof(stackframe)); stackframe.AddrPC.Mode = AddrModeFlat; stackframe.AddrStack.Mode = AddrModeFlat; stackframe.AddrFrame.Mode = AddrModeFlat; #if _M_IX86 stackframe.AddrPC.Offset = context.Eip; stackframe.AddrStack.Offset = context.Esp; stackframe.AddrFrame.Offset = context.Ebp; DWORD machine_arch = IMAGE_FILE_MACHINE_I386; #elif _M_X64 stackframe.AddrPC.Offset = context.Rip; stackframe.AddrStack.Offset = context.Rsp; stackframe.AddrFrame.Offset = context.Rbp; DWORD machine_arch = IMAGE_FILE_MACHINE_AMD64; #endif char symbol_buffer[1024]; ZeroMemory(symbol_buffer, sizeof(symbol_buffer)); PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(symbol_buffer); symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = sizeof(symbol_buffer) - sizeof(SYMBOL_INFO); Logger& logger(Logger::getSingleton()); logger.logEvent("========== Start of Backtrace ==========", Errors); size_t frame_no = 0; while (StackWalk64(machine_arch, GetCurrentProcess(), thread, &stackframe, &context, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0) && stackframe.AddrPC.Offset) { symbol->Address = stackframe.AddrPC.Offset; DWORD64 displacement = 0; char signature[256]; if (SymFromAddr(GetCurrentProcess(), symbol->Address, &displacement, symbol)) UnDecorateSymbolName(symbol->Name, signature, sizeof(signature), UNDNAME_COMPLETE); else sprintf_s(signature, sizeof(signature), "%p", symbol->Address); IMAGEHLP_MODULE64 modinfo; modinfo.SizeOfStruct = sizeof(modinfo); const BOOL have_image_name = SymGetModuleInfo64(GetCurrentProcess(), symbol->Address, &modinfo); char outstr[512]; sprintf_s(outstr, sizeof(outstr), "#%d %s +%#llx (%s)", frame_no, signature, displacement, (have_image_name ? modinfo.LoadedImageName : "????")); logger.logEvent(outstr, Errors); if (++frame_no >= frames) break; if (!stackframe.AddrReturn.Offset) break; } logger.logEvent("========== End of Backtrace ==========", Errors); SymCleanup(GetCurrentProcess()); #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__HAIKU__) void* buffer[frames]; const int received = backtrace(&buffer[0], frames); Logger& logger(Logger::getSingleton()); logger.logEvent("========== Start of Backtrace ==========", Errors); for (int i = 0; i < received; ++i) { char outstr[512]; Dl_info info; if (dladdr(buffer[i], &info)) { if (!info.dli_sname) snprintf(outstr, 512, "#%d %p (%s)", i, buffer[i], info.dli_fname); else { ptrdiff_t offset = static_cast<char*>(buffer[i]) - static_cast<char*>(info.dli_saddr); int demangle_result = 0; char* demangle_name = abi::__cxa_demangle(info.dli_sname, 0, 0, &demangle_result); snprintf(outstr, 512, "#%d %s +%#tx (%s)", i, demangle_name ? demangle_name : info.dli_sname, offset, info.dli_fname); std::free(demangle_name); } } else snprintf(outstr, 512, "#%d --- error ---", i); logger.logEvent(outstr, Errors); } logger.logEvent("========== End of Backtrace ==========", Errors); #endif #endif }
void jl_getDylibFunctionInfo(const char **name, int *line, const char **filename, size_t pointer, int skipC) { #ifdef _OS_WINDOWS_ DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer); if (fbase != 0) { #else Dl_info dlinfo; if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) { if (skipC && !jl_is_sysimg(dlinfo.dli_fname)) return; uint64_t fbase = (uint64_t)dlinfo.dli_fbase; #endif obfiletype::iterator it = objfilemap.find(fbase); llvm::object::ObjectFile *obj = NULL; DIContext *context = NULL; int64_t slide = 0; if (it == objfilemap.end()) { #ifdef _OS_DARWIN_ // First find the uuid of the object file (we'll use this to make sure we find the // correct debug symbol file). uint8_t uuid[16], uuid2[16]; #ifdef LLVM35 ErrorOr<llvm::object::ObjectFile*> origerrorobj = llvm::object::ObjectFile::createObjectFile( #else llvm::object::ObjectFile *origerrorobj = llvm::object::ObjectFile::createObjectFile( #endif MemoryBuffer::getMemBuffer( StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false) #ifdef LLVM35 ,false, sys::fs::file_magic::unknown #endif ); if (!origerrorobj) { objfileentry_t entry = {obj,context,slide}; objfilemap[fbase] = entry; return; } #ifdef LLVM35 llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get(); #else llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj; #endif if (!getObjUUID(morigobj,uuid)) { objfileentry_t entry = {obj,context,slide}; objfilemap[fbase] = entry; return; } // On OS X debug symbols are not contained in the dynamic library and that's why // we can't have nice things (easily). For now we only support .dSYM files in the same directory // as the shared library. In the future we may use DBGCopyFullDSYMURLForUUID from CoreFoundation to make // use of spotlight to find the .dSYM file. char dsympath[PATH_MAX]; strlcpy(dsympath, dlinfo.dli_fname, sizeof(dsympath)); strlcat(dsympath, ".dSYM/Contents/Resources/DWARF/", sizeof(dsympath)); strlcat(dsympath, strrchr(dlinfo.dli_fname,'/')+1, sizeof(dsympath)); #ifdef LLVM35 ErrorOr<llvm::object::ObjectFile*> errorobj = llvm::object::ObjectFile::createObjectFile(dsympath); #else llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(dsympath); #endif #else #ifndef _OS_WINDOWS_ const char *fname = dlinfo.dli_fname; #else IMAGEHLP_MODULE64 ModuleInfo; ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo); char *fname = ModuleInfo.LoadedImageName; JL_PRINTF(JL_STDOUT,fname); #endif // On non OS X systems we need to mmap another copy because of the permissions on the mmaped // shared library. #ifdef LLVM35 ErrorOr<llvm::object::ObjectFile*> errorobj = llvm::object::ObjectFile::createObjectFile(fname); #else llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(fname); #endif #endif #ifdef LLVM35 if (errorobj) { obj = errorobj.get(); #else if (errorobj != NULL) { obj = errorobj; #endif #ifdef _OS_DARWIN_ if (getObjUUID(morigobj,uuid2) && memcmp(uuid,uuid2,sizeof(uuid)) == 0) { #endif context = DIContext::getDWARFContext(obj); slide = -(uint64_t)fbase; #ifdef _OS_DARWIN_ } #endif #ifdef _OS_WINDOWS_ assert(obj->isCOFF()); llvm::object::COFFObjectFile *coffobj = (llvm::object::COFFObjectFile *)obj; const llvm::object::pe32plus_header *pe32plus; coffobj->getPE32PlusHeader(pe32plus); if (pe32plus != NULL) { slide = pe32plus->ImageBase-fbase; } else { const llvm::object::pe32_header *pe32; coffobj->getPE32Header(pe32); if (pe32 == NULL) { obj = NULL; context = NULL; } else { slide = pe32->ImageBase-fbase; } } #endif } objfileentry_t entry = {obj,context,slide}; objfilemap[fbase] = entry; } else { obj = it->second.obj; context = it->second.ctx; slide = it->second.slide; } lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(dlinfo.dli_fname)); } return; }
static void ShowSymbolInfo(HANDLE process, ULONG64 module_base) { /* Get module information. */ IMAGEHLP_MODULE64 module_info; BOOL getmoduleinfo_rv; printf("Load Address: %I64x\n", module_base); memset(&module_info, 0, sizeof(module_info)); module_info.SizeOfStruct = sizeof(module_info); getmoduleinfo_rv = SymGetModuleInfo64(process, module_base, &module_info); if (!getmoduleinfo_rv) { printf("Error: SymGetModuleInfo64() failed. Error code: %u\n", GetLastError()); return; } /* Display information about symbols, based on kind of symbol. */ switch (module_info.SymType) { case SymNone: printf(("No symbols available for the module.\n")); break; case SymExport: printf(("Loaded symbols: Exports\n")); break; case SymCoff: printf(("Loaded symbols: COFF\n")); break; case SymCv: printf(("Loaded symbols: CodeView\n")); break; case SymSym: printf(("Loaded symbols: SYM\n")); break; case SymVirtual: printf(("Loaded symbols: Virtual\n")); break; case SymPdb: printf(("Loaded symbols: PDB\n")); break; case SymDia: printf(("Loaded symbols: DIA\n")); break; case SymDeferred: printf(("Loaded symbols: Deferred\n")); /* not actually loaded */ break; default: printf(("Loaded symbols: Unknown format.\n")); break; } MaybePrint("Image name", module_info.ImageName); MaybePrint("Loaded image name", module_info.LoadedImageName); #ifdef VC8_OR_ABOVE /* TODO(csilvers): figure out how to tell */ MaybePrint("PDB file name", module_info.LoadedPdbName); if (module_info.PdbUnmatched || module_info.DbgUnmatched) { /* This can only happen if the debug information is contained in a * separate file (.DBG or .PDB) */ printf(("Warning: Unmatched symbols.\n")); } #endif /* Contents */ #ifdef VC8_OR_ABOVE /* TODO(csilvers): figure out how to tell */ PrintAvailability("Line numbers", module_info.LineNumbers); PrintAvailability("Global symbols", module_info.GlobalSymbols); PrintAvailability("Type information", module_info.TypeInfo); #endif }
std::vector<CallStackInfo> GetCallStack(const CONTEXT* pContext) { HANDLE hProcess = GetCurrentProcess(); SymInitialize(hProcess, NULL, TRUE); vector<CallStackInfo> arrCallStackInfo; CONTEXT c = *pContext; STACKFRAME64 sf; memset(&sf, 0, sizeof(STACKFRAME64)); DWORD dwImageType = IMAGE_FILE_MACHINE_I386; #ifdef _M_IX86 sf.AddrPC.Offset = c.Eip; sf.AddrPC.Mode = AddrModeFlat; sf.AddrStack.Offset = c.Esp; sf.AddrStack.Mode = AddrModeFlat; sf.AddrFrame.Offset = c.Ebp; sf.AddrFrame.Mode = AddrModeFlat; #elif _M_X64 dwImageType = 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; #elif _M_IA64 dwImageType = 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; #else #error "Platform not supported!" #endif HANDLE hThread = GetCurrentThread(); while (true) { if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; if (sf.AddrFrame.Offset == 0) break; CallStackInfo callstackinfo; strcpy_s(callstackinfo.MethodName, MAX_NAME_LENGTH, "N/A"); strcpy_s(callstackinfo.FileName, MAX_NAME_LENGTH, "N/A"); strcpy_s(callstackinfo.ModuleName, MAX_NAME_LENGTH, "N/A"); strcpy_s(callstackinfo.LineNumber, MAX_NAME_LENGTH, "N/A"); BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_NAME_LENGTH]; IMAGEHLP_SYMBOL64 *pSymbol = (IMAGEHLP_SYMBOL64*)symbolBuffer; memset(pSymbol, 0, sizeof(IMAGEHLP_SYMBOL64) + MAX_NAME_LENGTH); pSymbol->SizeOfStruct = sizeof(symbolBuffer); pSymbol->MaxNameLength = MAX_NAME_LENGTH; DWORD symDisplacement = 0; // 得到函数名 if (SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, NULL, pSymbol)) strcpy_s(callstackinfo.MethodName, MAX_NAME_LENGTH, pSymbol->Name); IMAGEHLP_LINE64 lineInfo; memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64)); lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); DWORD dwLineDisplacement; // 得到文件名和所在的代码行 if (SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo)) { strcpy_s(callstackinfo.FileName, MAX_NAME_LENGTH, lineInfo.FileName); sprintf_s(callstackinfo.LineNumber, "%d", lineInfo.LineNumber); } IMAGEHLP_MODULE64 moduleInfo; memset(&moduleInfo, 0, sizeof(IMAGEHLP_MODULE64)); moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); // 得到模块名 if (SymGetModuleInfo64(hProcess, sf.AddrPC.Offset, &moduleInfo)) { strcpy_s(callstackinfo.ModuleName, MAX_NAME_LENGTH, moduleInfo.ModuleName); } arrCallStackInfo.push_back(callstackinfo); } SymCleanup(hProcess); return arrCallStackInfo; }
int CMiniDumpReader::StackWalk(DWORD dwThreadId) { int nThreadIndex = GetThreadRowIdByThreadId(dwThreadId); if(m_DumpData.m_Threads[nThreadIndex].m_bStackWalk == TRUE) return 0; // Already done CONTEXT* pThreadContext = NULL; if(m_DumpData.m_Threads[nThreadIndex].m_dwThreadId==m_DumpData.m_uExceptionThreadId) pThreadContext = m_DumpData.m_pExceptionThreadContext; else pThreadContext = m_DumpData.m_Threads[nThreadIndex].m_pThreadContext; if(pThreadContext==NULL) return 1; // Make modifiable context CONTEXT Context; memcpy(&Context, pThreadContext, sizeof(CONTEXT)); g_pMiniDumpReader = this; // Init stack frame with correct initial values // See this: // http://www.codeproject.com/KB/threads/StackWalker.aspx // // Given a current dbghelp, your code should: // 1. Always use StackWalk64 // 2. Always set AddrPC to the current instruction pointer (Eip on x86, Rip on x64 and StIIP on IA64) // 3. Always set AddrStack to the current stack pointer (Esp on x86, Rsp on x64 and IntSp on IA64) // 4. Set AddrFrame to the current frame pointer when meaningful. On x86 this is Ebp, on x64 you // can use Rbp (but is not used by VC2005B2; instead it uses Rdi!) and on IA64 you can use RsBSP. // StackWalk64 will ignore the value when it isn't needed for unwinding. // 5. Set AddrBStore to RsBSP for IA64. STACKFRAME64 sf; memset(&sf, 0, sizeof(STACKFRAME64)); sf.AddrPC.Mode = AddrModeFlat; sf.AddrFrame.Mode = AddrModeFlat; sf.AddrStack.Mode = AddrModeFlat; sf.AddrBStore.Mode = AddrModeFlat; DWORD dwMachineType = 0; switch(m_DumpData.m_uProcessorArchitecture) { #ifdef _X86_ case PROCESSOR_ARCHITECTURE_INTEL: dwMachineType = IMAGE_FILE_MACHINE_I386; sf.AddrPC.Offset = pThreadContext->Eip; sf.AddrStack.Offset = pThreadContext->Esp; sf.AddrFrame.Offset = pThreadContext->Ebp; break; #endif #ifdef _AMD64_ case PROCESSOR_ARCHITECTURE_AMD64: dwMachineType = IMAGE_FILE_MACHINE_AMD64; sf.AddrPC.Offset = pThreadContext->Rip; sf.AddrStack.Offset = pThreadContext->Rsp; sf.AddrFrame.Offset = pThreadContext->Rbp; break; #endif #ifdef _IA64_ case PROCESSOR_ARCHITECTURE_AMD64: dwMachineType = IMAGE_FILE_MACHINE_IA64; sf.AddrPC.Offset = pThreadContext->StIIP; sf.AddrStack.Offset = pThreadContext->IntSp; sf.AddrFrame.Offset = pThreadContext->RsBSP; sf.AddrBStore.Offset = pThreadContext->RsBSP; break; #endif default: { assert(0); return 1; // Unsupported architecture } } for(;;) { BOOL bWalk = ::StackWalk64( dwMachineType, // machine type m_DumpData.m_hProcess, // our process handle (HANDLE)dwThreadId, // thread ID &sf, // stack frame dwMachineType==IMAGE_FILE_MACHINE_I386?NULL:(&Context), // used for non-I386 machines ReadProcessMemoryProc64, // our routine FunctionTableAccessProc64, // our routine GetModuleBaseProc64, // our routine NULL // safe to be NULL ); if(!bWalk) break; MdmpStackFrame stack_frame; stack_frame.m_dwAddrPCOffset = sf.AddrPC.Offset; // Get module info IMAGEHLP_MODULE64 mi; memset(&mi, 0, sizeof(IMAGEHLP_MODULE64)); mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); BOOL bGetModuleInfo = SymGetModuleInfo64(m_DumpData.m_hProcess, sf.AddrPC.Offset, &mi); if(bGetModuleInfo) { stack_frame.m_nModuleRowID = GetModuleRowIdByBaseAddr(mi.BaseOfImage); } // Get symbol info DWORD64 dwDisp64; BYTE buffer[4096]; SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer; sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); sym_info->MaxNameLen = 4096-sizeof(SYMBOL_INFO)-1; BOOL bGetSym = SymFromAddr( m_DumpData.m_hProcess, sf.AddrPC.Offset, &dwDisp64, sym_info); if(bGetSym) { stack_frame.m_sSymbolName = CString(sym_info->Name, sym_info->NameLen); stack_frame.m_dw64OffsInSymbol = dwDisp64; } // Get source filename and line DWORD dwDisplacement; IMAGEHLP_LINE64 line; BOOL bGetLine = SymGetLineFromAddr64( m_DumpData.m_hProcess, sf.AddrPC.Offset, &dwDisplacement, &line); if(bGetLine) { stack_frame.m_sSrcFileName = line.FileName; stack_frame.m_nSrcLineNumber = line.LineNumber; } m_DumpData.m_Threads[nThreadIndex].m_StackTrace.push_back(stack_frame); } CString sStackTrace; UINT i; for(i=0; i<m_DumpData.m_Threads[nThreadIndex].m_StackTrace.size(); i++) { MdmpStackFrame& frame = m_DumpData.m_Threads[nThreadIndex].m_StackTrace[i]; if(frame.m_sSymbolName.IsEmpty()) continue; CString sModuleName; CString sAddrPCOffset; CString sSymbolName; CString sOffsInSymbol; CString sSourceFile; CString sSourceLine; if(frame.m_nModuleRowID>=0) { sModuleName = m_DumpData.m_Modules[frame.m_nModuleRowID].m_sModuleName; } sSymbolName = frame.m_sSymbolName; sAddrPCOffset.Format(_T("0x%I64x"), frame.m_dwAddrPCOffset); sSourceFile = frame.m_sSrcFileName; sSourceLine.Format(_T("%d"), frame.m_nSrcLineNumber); sOffsInSymbol.Format(_T("0x%I64x"), frame.m_dw64OffsInSymbol); CString str; str = sModuleName; if(!str.IsEmpty()) str += _T("!"); if(sSymbolName.IsEmpty()) str += sAddrPCOffset; else { str += sSymbolName; str += _T("+"); str += sOffsInSymbol; } if(!sSourceFile.IsEmpty()) { size_t pos = sSourceFile.ReverseFind('\\'); if(pos>=0) sSourceFile = sSourceFile.Mid((int)pos+1); str += _T(" [ "); str += sSourceFile; str += _T(": "); str += sSourceLine; str += _T(" ] "); } sStackTrace += str; sStackTrace += _T("\n"); } if(!sStackTrace.IsEmpty()) { strconv_t strconv; LPCSTR szStackTrace = strconv.t2utf8(sStackTrace); MD5 md5; MD5_CTX md5_ctx; unsigned char md5_hash[16]; md5.MD5Init(&md5_ctx); md5.MD5Update(&md5_ctx, (unsigned char*)szStackTrace, (unsigned int)strlen(szStackTrace)); md5.MD5Final(md5_hash, &md5_ctx); for(i=0; i<16; i++) { CString number; number.Format(_T("%02x"), md5_hash[i]); m_DumpData.m_Threads[nThreadIndex].m_sStackTraceMD5 += number; } } m_DumpData.m_Threads[nThreadIndex].m_bStackWalk = TRUE; return 0; }
static std::list<stack_info> get_stack_list( void* bp, void* sp, void* ip, size_t max_depth, size_t offset, bool module, bool symbol, bool brief ) { QWORD trace[33]; CONTEXT context; ZeroMemory(&context, sizeof(context)); context.ContextFlags = CONTEXT_FULL; #ifdef _WIN64 context.Rbp = (DWORD64)bp; context.Rsp = (DWORD64)sp; context.Rip = (DWORD64)ip; #else context.Ebp = (DWORD)bp; context.Esp = (DWORD)sp; context.Eip = (DWORD)ip; #endif size_t depths = stack_walk(trace, max_depth, &context); std::list<stack_info> image_list; HANDLE hProcess = GetCurrentProcess(); for (size_t i = offset; i < depths; i++) { stack_info stack_result(brief); { DWORD symbolDisplacement = 0; IMAGEHLP_LINE64 imageHelpLine; imageHelpLine.SizeOfStruct = sizeof(imageHelpLine); if (SymGetLineFromAddr64(hProcess, trace[i], &symbolDisplacement, &imageHelpLine)) { stack_result.file_ = std::string(imageHelpLine.FileName, check_file_name(imageHelpLine.FileName)); std::memset(imageHelpLine.FileName, 0, stack_result.file_.size() + 1); stack_result.line_ = (int)imageHelpLine.LineNumber; } else { stack_result.line_ = -1; } } if (symbol) { static const int max_name_length = 1024; char symbolBf[sizeof(IMAGEHLP_SYMBOL64) + max_name_length] = { 0 }; PIMAGEHLP_SYMBOL64 symbol; DWORD64 symbolDisplacement64 = 0; symbol = (PIMAGEHLP_SYMBOL64)symbolBf; symbol->SizeOfStruct = sizeof(symbolBf); symbol->MaxNameLength = max_name_length; if (SymGetSymFromAddr64( hProcess, trace[i], &symbolDisplacement64, symbol) ) { stack_result.symbol_ = symbol->Name; } else { stack_result.symbol_ = "unknow..."; } } if (module) { IMAGEHLP_MODULE64 imageHelpModule; imageHelpModule.SizeOfStruct = sizeof(imageHelpModule); if (SymGetModuleInfo64(hProcess, trace[i], &imageHelpModule)) { stack_result.module_ = std::string(imageHelpModule.ImageName, check_file_name(imageHelpModule.ImageName)); std::memset(imageHelpModule.ImageName, 0, stack_result.module_.size() + 1); } } image_list.push_back(std::move(stack_result)); } return image_list; }
void WINAPI CConsumer::ProcessEvent(PEVENT_TRACE pEvent) { WCHAR ClassGuid[50]; IWbemClassObject *pEventCategoryClass = NULL; IWbemClassObject *pEventClass = NULL; PBYTE pEventData = NULL; PBYTE pEndOfEventData = NULL; PROPERTY_LIST *pProperties = NULL; DWORD PropertyCount = 0; LONG *pProPertyIndex = NULL; ULONGLONG TimeStamp = 0; SYSTEMTIME st; SYSTEMTIME stLocal; FILETIME ft; ULONG diskReadTransfer = 0; UINT64 highResResponseTime = 0; DWORD threadId = 0; if(!m_isContinueTrace && !IsEqualGUID(pEvent->Header.Guid, FileIoGuid)) return ; UINT32 instrumentPointer = 0; if(IsEqualGUID(pEvent->Header.Guid, EventTraceGuid) && EVENT_TRACE_TYPE_INFO == pEvent->Header.Class.Type ) { ; // Skip this Event. } else { StringFromGUID2(pEvent->Header.Guid, ClassGuid, sizeof(ClassGuid)); TimeStamp = pEvent->Header.TimeStamp.QuadPart; pEventData = (PBYTE) pEvent->MofData; UCHAR eventType = pEvent->Header.Class.Type; if(IsEqualGUID(pEvent->Header.Guid,ProcessGuid) && pEvent->MofLength > 0) { if(eventType == EVENT_TRACE_TYPE_START) { UINT32 processID; CopyMemory(&processID, pEventData+MOF_POINTERSIZE, sizeof(UINT32)); if(processID == m_processId) m_processStartSamp.QuadPart = TimeStamp; } } if(IsEqualGUID(pEvent->Header.Guid, PageFaultGuid) && pEvent->MofData > 0) { if(32 == eventType) // hard faults { CopyMemory(&threadId, pEventData+16+2*MOF_POINTERSIZE, sizeof(UINT32)); for(std::vector<DWORD>::iterator ite = m_vecThreadId.begin(); ite != m_vecThreadId.end(); ++ite) { if(*ite == threadId ) { UINT64 readOffset, vtAddr, fileObject,initTimeStamp; UINT32 byteCount = 0; CopyMemory(&initTimeStamp, pEventData, 8); CopyMemory(&readOffset, pEventData+8, 8); CopyMemory(&vtAddr, pEventData + 16, MOF_POINTERSIZE); CopyMemory(&fileObject, pEventData +16+MOF_POINTERSIZE, MOF_POINTERSIZE); CopyMemory(&byteCount, pEventData+20+2*MOF_POINTERSIZE, sizeof(UINT32)); CHardFaults hardFaultsTemp; hardFaultsTemp.initTime = initTimeStamp; hardFaultsTemp.fileObj = fileObject; hardFaultsTemp.fileOffset = readOffset; hardFaultsTemp.vtAddress = vtAddr; hardFaultsTemp.byteCount = byteCount; MAP_FILEOBJ_ITE mapIte = m_mapFileObjectToFileName.begin(); for(; mapIte != m_mapFileObjectToFileName.end() ; ++mapIte) { if(mapIte->first == hardFaultsTemp.fileObj) break; } if(mapIte == m_mapFileObjectToFileName.end()) { m_vecHardFaults.push_back(hardFaultsTemp); } else { VEC_FILEFAULTS_ITE iteFaults; for(iteFaults = m_vecFileFaults.begin(); iteFaults != m_vecFileFaults.end(); ++iteFaults) { if(wcscmp(iteFaults->fileName.c_str(), mapIte->second.c_str()) == 0 ) break; } if(iteFaults != m_vecFileFaults.end()) { iteFaults->faultCount += 1; iteFaults->readSize += hardFaultsTemp.byteCount; iteFaults->vec_Fault.push_back(hardFaultsTemp); } else { CFileHardFaults fileHardFaults; fileHardFaults.fileObj = mapIte->first; fileHardFaults.faultCount = 1; fileHardFaults.readSize = hardFaultsTemp.byteCount; fileHardFaults.fileName = mapIte->second; fileHardFaults.vec_Fault.push_back(hardFaultsTemp); m_vecFileFaults.push_back(fileHardFaults); } } break; } } } } if(IsEqualGUID(pEvent->Header.Guid, StackWalkGuid) && pEvent->MofLength > 0 ) { int processId = 0; CopyMemory(&processId, pEventData + 8, 4); if(processId == m_processId) { BOOL bRet = FALSE; UINT64 TimeStamp=0; // 具体事件触发时候的时间戳, CopyMemory(&TimeStamp, pEventData, sizeof(UINT64)); if(m_preStackWalkStamp == 0) { m_preStackWalkStamp= TimeStamp; return; } int stackFrameCount = (pEvent->MofLength - 16)/MOF_POINTERSIZE; UINT64 stack1 = 0; CopyMemory(&stack1, pEventData+16, MOF_POINTERSIZE); if(INT64(stack1) < 0 ) return ; std::vector<std::string> vecTemp; for(int i=0; i < stackFrameCount; ++i) { std::string sym; UINT64 stackEnd = 0; CopyMemory(&stackEnd, pEventData+16+i*MOF_POINTERSIZE, MOF_POINTERSIZE); DWORD64 dwDisp64; BYTE buffer[4096]; SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer; sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); sym_info->MaxNameLen = 4096-sizeof(SYMBOL_INFO)-1; BOOL bGetSym = SymFromAddr(m_processHandle,stackEnd,&dwDisp64, sym_info); IMAGEHLP_MODULE64 mi; memset(&mi, 0, sizeof(IMAGEHLP_MODULE64)); mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); BOOL bGetModuleInfo = SymGetModuleInfo64(m_processHandle, stackEnd, &mi); if(bGetModuleInfo) sym = (std::string)(mi.ModuleName) + "!"; if(bGetSym) sym = sym + sym_info->Name; char stackAddress[64] = {0}; _i64toa_s(stackEnd, stackAddress,64, 16); sym += "(0x"; sym += stackAddress; sym += ")"; vecTemp.push_back(sym); } SAMPLE_STACK sampleStack; sampleStack.timeStamp = TimeStamp; sampleStack.timeInterval = TimeStamp - m_preStackWalkStamp; sampleStack.vecStack = vecTemp; m_vecSampleStack.push_back(sampleStack); m_preStackWalkStamp = TimeStamp; } } if(IsEqualGUID(pEvent->Header.Guid, FileIoGuid) && pEvent->MofLength > 0) { UINT64 fileObjectPtr = 0; wchar_t fileName[MAX_PATH] = {0}; if( 0 == eventType || 32 == eventType || 35 == eventType || 36 == eventType) { int lenth = wcslen((wchar_t*)(pEventData+MOF_POINTERSIZE)); CopyMemory(fileName, pEventData+MOF_POINTERSIZE, lenth*sizeof(wchar_t)); CopyMemory(&fileObjectPtr, pEventData, MOF_POINTERSIZE); m_mapFileObjectToFileName[fileObjectPtr] = fileName; } // if(64 == eventType) //创建文件 // { // int lenth = wcslen((wchar_t*) (pEventData + 12 + MOF_POINTERSIZE*3)); // CopyMemory(fileName, pEventData + 12 + MOF_POINTERSIZE*3, lenth*sizeof(wchar_t)); // CopyMemory(&fileObjectPtr, pEventData + 2*MOF_POINTERSIZE, MOF_POINTERSIZE); // m_mapFileCreate[fileObjectPtr] = fileName; // } // // if(67 == eventType || 68 == eventType) //文件读写 // { // UINT64 fileCreateObj; // CopyMemory(&fileCreateObj, pEventData + 8 + 2*MOF_POINTERSIZE, MOF_POINTERSIZE); // CopyMemory(&fileObjectPtr, pEventData + 8 + 3*MOF_POINTERSIZE, MOF_POINTERSIZE); // MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj); // if(iteCreate != m_mapFileCreate.end()) // { // m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second; // } // // } // // if(65 == eventType || 66 == eventType || 73 == eventType) // { // UINT64 fileCreateObj; // CopyMemory(&fileCreateObj, pEventData + 2*MOF_POINTERSIZE, MOF_POINTERSIZE); // CopyMemory(&fileObjectPtr, pEventData + 3*MOF_POINTERSIZE, MOF_POINTERSIZE); // MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj); // if(iteCreate != m_mapFileCreate.end()) // { // m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second; // } // } // // if(69 == eventType || 70 == eventType || 71 == eventType || 74 == eventType || 75 == eventType) // { // UINT64 fileCreateObj; // CopyMemory(&fileCreateObj, pEventData + 2*MOF_POINTERSIZE, MOF_POINTERSIZE); // CopyMemory(&fileObjectPtr, pEventData + 3*MOF_POINTERSIZE, MOF_POINTERSIZE); // MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj); // if(iteCreate != m_mapFileCreate.end()) // { // m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second; // } // } // // if(72 == eventType || 77 == eventType) // { // // int lenth = wcslen((wchar_t*) (pEventData+8 + 5*MOF_POINTERSIZE)); // // CopyMemory(fileName, pEventData+8 + 5*MOF_POINTERSIZE, lenth*sizeof(wchar_t)); // UINT64 fileCreateObj; // CopyMemory(&fileCreateObj, pEventData+2*MOF_POINTERSIZE, MOF_POINTERSIZE); // CopyMemory(&fileObjectPtr,pEventData+3*MOF_POINTERSIZE,MOF_POINTERSIZE); // MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj); // if(iteCreate != m_mapFileCreate.end()) // { // m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second; // } // } } if(IsEqualGUID(pEvent->Header.Guid,MyCategoryGuid)) { if(THUNDER_PROVIDER_TYPE_END == pEvent->Header.Class.Type) { m_isContinueTrace = FALSE; m_startTimeUsed.QuadPart = TimeStamp - m_processStartSamp.QuadPart; } } if(IsEqualGUID(pEvent->Header.Guid, ThreadGuid) && pEvent->MofLength > 0) { DWORD processID = 0; CopyMemory(&processID, pEventData, 4); if(EVENT_TRACE_TYPE_START == pEvent->Header.Class.Type /*|| 3 == pEvent->Header.Class.Type*/) { if(m_processId == processID ) { CopyMemory(&threadId, pEventData + 4, 4); m_vecThreadId.push_back(threadId); } } if(EVENT_TRACE_TYPE_END == pEvent->Header.Class.Type) { if(m_processId == processID) { CopyMemory(&threadId, pEventData + 4, 4); for(std::vector<DWORD>::iterator ite = m_vecThreadId.begin(); ite != m_vecThreadId.end(); ++ite) { if(*ite == threadId) { m_vecThreadId.erase(ite); break; } } } } } if(IsEqualGUID(pEvent->Header.Guid, PerfInfoGuid) && pEvent->MofLength > 0) { if(m_processStartSamp.QuadPart == 0) // 进程还没开始 return; if(46 == pEvent->Header.Class.Type) // sample profile { if(m_beginTimeStamp == 0) m_beginTimeStamp = TimeStamp; m_endTimeStamp = TimeStamp; m_totalSampleCount += 1; DWORD perfThreadId = -1; CopyMemory(&perfThreadId, pEventData+8, 4); for(std::vector<DWORD>::iterator ite = m_vecThreadId.begin(); ite != m_vecThreadId.end(); ++ite) { if(*ite == perfThreadId ) { m_processSampleCount += 1; break; } } } } if(IsEqualGUID(pEvent->Header.Guid, DiskIoGuid ) && pEvent->MofLength > 0) { if((EVENT_TRACE_TYPE_IO_READ == pEvent->Header.Class.Type || EVENT_TRACE_TYPE_IO_WRITE == pEvent->Header.Class.Type) && pEvent->Header.ProcessId == m_processId) { // pEventCategoryClass = GetEventCategoryClass(_bstr_t(ClassGuid), pEvent->Header.Version); // if(pEventCategoryClass) // { // pEventClass = GetEventClass(pEventCategoryClass, pEvent->Header.Class.Type); // pEventCategoryClass->Release(); // pEventCategoryClass = NULL; // if(pEventClass) // { // if(TRUE == GetPropertyList(pEventClass, &pProperties, &PropertyCount, &pProPertyIndex)) // { CopyMemory(&diskReadTransfer, pEventData + sizeof(UINT32) + sizeof(UINT32), sizeof(ULONG)); CopyMemory(&highResResponseTime, pEventData + 24+2*MOF_POINTERSIZE, sizeof(ULONGLONG)); LARGE_INTEGER Frequency; QueryPerformanceFrequency(&Frequency); highResResponseTime = highResResponseTime * 1000000 / Frequency.QuadPart; m_totalReadTime += highResResponseTime; m_totalReadBytes += diskReadTransfer; TimeStamp = pEvent->Header.TimeStamp.QuadPart; UINT64 fileObjectPtr = 0; CopyMemory(&fileObjectPtr, pEventData + 24, MOF_POINTERSIZE); MAP_FILEOBJ_ITE mapIte = m_mapFileObjectToFileName.begin(); for(; mapIte != m_mapFileObjectToFileName.end() ; ++mapIte) { if(mapIte->first == fileObjectPtr) break; } if(mapIte == m_mapFileObjectToFileName.end()) { fileIoInfo fileIo; ZeroMemory(&fileIo,sizeof(fileIo)); fileIo.fileIoSize = diskReadTransfer; fileIo.fileObjectPtr = fileObjectPtr; fileIo.fileIoTime = highResResponseTime; m_vecNotFindPtrFile.push_back(fileIo); } else { VEC_FILEINFO_ITE ite = m_vecFileIoInfo.begin(); for(; ite != m_vecFileIoInfo.end(); ++ite) { if(ite->fileObjectPtr == fileObjectPtr && wcscmp(ite->fileName.c_str(), mapIte->second.c_str()) == 0 ) { ite->fileIoSize += diskReadTransfer; ite->fileIoTime += highResResponseTime; break; } } if(ite == m_vecFileIoInfo.end()) { fileIoInfo fileIo; ZeroMemory(&fileIo,sizeof(fileIo)); fileIo.fileName = mapIte->second; fileIo.fileIoSize = diskReadTransfer; fileIo.fileObjectPtr = fileObjectPtr; fileIo.fileIoTime = highResResponseTime; m_vecFileIoInfo.push_back(fileIo); } } // PBYTE pEndEventData = pEventData + pEvent->MofLength; // PBYTE pEventPre = pEventData; // for(int i=0; i < PropertyCount; ++i) // { // PrintPropertyName(pProperties + pProPertyIndex[i]); // pEventData = PrintEventPropertyValue(pProperties + pProPertyIndex[i], pEventData, pEndEventData - pEventData); // wprintf(L"ofsset of property :%d", pEventData - pEventPre); // } // // } // } // } } } } }