BOOL AddressToName(DWORD Addr, LPTSTR Str, int Max) { DWORD base; if (!InitialiseImageHelp()) return FALSE; base = SymGetModuleBase(s_hProcess, Addr); if (base) { struct { IMAGEHLP_SYMBOL ihs; char NameBuf[256]; } SymInfo; DWORD Displacement = 0; SymInfo.ihs.SizeOfStruct = sizeof(SymInfo); SymInfo.ihs.MaxNameLength = sizeof(SymInfo.NameBuf); if (SymGetSymFromAddr(s_hProcess, Addr, &Displacement, &SymInfo.ihs)) { if (Displacement) _snprintf(Str, Max-1, "%s+%x", SymInfo.ihs.Name, Displacement); else _snprintf(Str, Max-1, "%s", SymInfo.ihs.Name); return TRUE; } else { _snprintf(Str, Max, "SymGetSymFromAddr failed (%d)", GetLastError()); } } else { _snprintf(Str, Max, "SymGetModuleBase failed (%d)", GetLastError()); } return FALSE; }
static ULONG_ADDR CALLBACK GetModuleBase(HANDLE hProcess, ULONG_ADDR dwAddress) { MEMORY_BASIC_INFORMATION memoryInfo; ULONG_ADDR dwAddrBase = SymGetModuleBase(hProcess, dwAddress); if (dwAddrBase) { return dwAddrBase; } if (VirtualQueryEx(hProcess, (void*)(GC_ULONG_PTR)dwAddress, &memoryInfo, sizeof(memoryInfo))) { char filePath[_MAX_PATH]; char curDir[_MAX_PATH]; char exePath[_MAX_PATH]; DWORD size = GetModuleFileNameA((HINSTANCE)memoryInfo.AllocationBase, filePath, sizeof(filePath)); /* Save and restore current directory around SymLoadModule, see KB */ /* article Q189780. */ GetCurrentDirectoryA(sizeof(curDir), curDir); GetModuleFileNameA(NULL, exePath, sizeof(exePath)); #if defined(_MSC_VER) && _MSC_VER == 1200 /* use strcat for VC6 */ strcat(exePath, "\\.."); #else strcat_s(exePath, sizeof(exePath), "\\.."); #endif /* _MSC_VER >= 1200 */ SetCurrentDirectoryA(exePath); #ifdef _DEBUG GetCurrentDirectoryA(sizeof(exePath), exePath); #endif SymLoadModule(hProcess, NULL, size ? filePath : NULL, NULL, (ULONG_ADDR)(GC_ULONG_PTR)memoryInfo.AllocationBase, 0); SetCurrentDirectoryA(curDir); } return (ULONG_ADDR)(GC_ULONG_PTR)memoryInfo.AllocationBase; }
void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss) { PIMAGEHLP_SYMBOL pSym; STACKFRAME sf; HANDLE process, thread; ULONG_PTR dwModBase, Disp; BOOL more = FALSE; DWORD machineType; int count = 0; char modname[MAX_PATH]; char symBuffer[sizeof(IMAGEHLP_SYMBOL) + 255]; pSym = (PIMAGEHLP_SYMBOL)symBuffer; ZeroMemory(&sf, sizeof(sf)); #ifdef _WIN64 sf.AddrPC.Offset = e->ContextRecord->Rip; sf.AddrStack.Offset = e->ContextRecord->Rsp; sf.AddrFrame.Offset = e->ContextRecord->Rbp; machineType = IMAGE_FILE_MACHINE_AMD64; #else sf.AddrPC.Offset = e->ContextRecord->Eip; sf.AddrStack.Offset = e->ContextRecord->Esp; sf.AddrFrame.Offset = e->ContextRecord->Ebp; machineType = IMAGE_FILE_MACHINE_I386; #endif sf.AddrPC.Mode = AddrModeFlat; sf.AddrStack.Mode = AddrModeFlat; sf.AddrFrame.Mode = AddrModeFlat; process = GetCurrentProcess(); thread = GetCurrentThread(); while(1) { more = StackWalk(machineType, process, thread, &sf, e->ContextRecord, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL); if(!more || sf.AddrFrame.Offset == 0) break; dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset); if(dwModBase) GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH); else strcpy(modname, "Unknown"); Disp = 0; pSym->SizeOfStruct = sizeof(symBuffer); pSym->MaxNameLength = 254; if(SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym)) ss << stdext::format(" %d: %s(%s+%#0lx) [0x%016lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset); else ss << stdext::format(" %d: %s [0x%016lX]\n", count, modname, sf.AddrPC.Offset); ++count; } GlobalFree(pSym); }
unsigned dbgsymengine::module(char * buf, unsigned len) { if (!len || !buf || IsBadWritePtr(buf, len)) return 0; if (!check()) return 0; HANDLE hProc = SymGetProcessHandle(); HMODULE hMod = (HMODULE)SymGetModuleBase (hProc, m_address); if (!hMod) return 0; return get_module_basename(hMod, buf, len); }
bool dbgsymengine::stack_next () { if (!m_pframe || !m_pctx) { _ASSERTE(0); return false; } if (!m_ok) { _ASSERTE(0); return false; } SetLastError(0); HANDLE hProc = SymGetProcessHandle(); BOOL r = StackWalk (IMAGE_FILE_MACHINE_I386, hProc, GetCurrentThread(), m_pframe, m_pctx, (PREAD_PROCESS_MEMORY_ROUTINE)My_ReadProcessMemory, SymFunctionTableAccess, SymGetModuleBase, 0); if (!r || !m_pframe->AddrFrame.Offset) { return false; } // "Debugging Applications" John Robbins // Before I get too carried away and start calculating // everything, I need to double-check that the address returned // by StackWalk really exists. I've seen cases in which // StackWalk returns TRUE but the address doesn't belong to // a module in the process. DWORD dwModBase = SymGetModuleBase (hProc, m_pframe->AddrPC.Offset); if (!dwModBase) { _ASSERTE(0); return false; } address(m_pframe->AddrPC.Offset); return true; }
void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss) { PIMAGEHLP_SYMBOL pSym; STACKFRAME sf; HANDLE process, thread; DWORD dwModBase, Disp; BOOL more = FALSE; int count = 0; char modname[MAX_PATH]; pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384); ZeroMemory(&sf, sizeof(sf)); sf.AddrPC.Offset = e->ContextRecord->Eip; sf.AddrStack.Offset = e->ContextRecord->Esp; sf.AddrFrame.Offset = e->ContextRecord->Ebp; sf.AddrPC.Mode = AddrModeFlat; sf.AddrStack.Mode = AddrModeFlat; sf.AddrFrame.Mode = AddrModeFlat; process = GetCurrentProcess(); thread = GetCurrentThread(); while(1) { more = StackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &sf, e->ContextRecord, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL); if(!more || sf.AddrFrame.Offset == 0) break; dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset); if(dwModBase) GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH); else strcpy(modname, "Unknown"); pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); pSym->MaxNameLength = MAX_PATH; if(SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym)) ss << stdext::format(" %d: %s(%s+%#0lx) [0x%08lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset); else ss << stdext::format(" %d: %s [0x%08lX]\n", count, modname, sf.AddrPC.Offset); ++count; } GlobalFree(pSym); }
static void _backtrace(int depth , LPCONTEXT context) { STACKFRAME frame; char module_name_raw[MAX_PATH]; LbMemorySet(&frame,0,sizeof(frame)); frame.AddrPC.Offset = context->Eip; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Offset = context->Esp; frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Offset = context->Ebp; frame.AddrFrame.Mode = AddrModeFlat; HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); while (StackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &frame, context, 0, SymFunctionTableAccess, SymGetModuleBase, 0)) { --depth; if (depth < 0) break; DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset); const char * module_name = "[unknown module]"; if (module_base && GetModuleFileNameA((HINSTANCE)module_base, module_name_raw, MAX_PATH)) { module_name = strrchr(module_name_raw,'\\'); if (module_name != NULL) module_name++; else module_name = module_name_raw; } LbJustLog(" in %s at %04x:%08x, base %08x\n", module_name, context->SegCs, frame.AddrPC.Offset, module_base); } }
static bool DumpFrame(void *process, DWORD_PTR frameAddress) { const int functionLength = 255; IMAGEHLP_SYMBOL *symbol = (IMAGEHLP_SYMBOL*)malloc(sizeof(IMAGEHLP_SYMBOL) + functionLength); DWORD_PTR moduleBase = SymGetModuleBase(process, frameAddress); const char *moduleName = NULL, *functionName = NULL; DWORD_PTR displacement; char moduleFilename[MAX_PATH]; symbol->SizeOfStruct = (sizeof(*symbol)) + functionLength; symbol->MaxNameLength = functionLength - 1; if (moduleBase && GetModuleFileName((HINSTANCE)moduleBase, moduleFilename, MAX_PATH)) moduleName = moduleFilename; if (SymGetSymFromAddr(process, frameAddress, &displacement, symbol)) functionName = symbol->Name; PrintFunction(moduleName, functionName, frameAddress, displacement); free(symbol); }
static void _backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT context) { char procname[MAX_PATH]; GetModuleFileNameA(NULL, procname, sizeof procname); struct bfd_ctx *bc = NULL; STACKFRAME frame; memset(&frame,0,sizeof(frame)); frame.AddrPC.Offset = context->Eip; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Offset = context->Esp; frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Offset = context->Ebp; frame.AddrFrame.Mode = AddrModeFlat; HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + 255]; char module_name_raw[MAX_PATH]; while(StackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &frame, context, 0, SymFunctionTableAccess, SymGetModuleBase, 0)) { --depth; if (depth < 0) break; IMAGEHLP_SYMBOL *symbol = (IMAGEHLP_SYMBOL *)symbol_buffer; symbol->SizeOfStruct = (sizeof *symbol) + 255; symbol->MaxNameLength = 254; DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset); const char * module_name = "[unknown module]"; if (module_base && GetModuleFileNameA((HINSTANCE)module_base, module_name_raw, MAX_PATH)) { module_name = module_name_raw; bc = get_bc(ob, set, module_name); } const char * file = NULL; const char * func = NULL; unsigned line = 0; if (bc) { find(bc,frame.AddrPC.Offset,&file,&func,&line); } if (file == NULL) { DWORD dummy = 0; if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol)) { file = symbol->Name; } else { file = "[unknown file]"; } } if (func == NULL) { output_print(ob,"0x%x : %s : %s \n", frame.AddrPC.Offset, module_name, file); } else { output_print(ob,"0x%x : %s : %s (%d) : in function (%s) \n", frame.AddrPC.Offset, module_name, file, line, func); } } }
/** Print out a stacktrace. */ static void Stacktrace(const char *threadName, LPEXCEPTION_POINTERS e, HANDLE hThread = INVALID_HANDLE_VALUE) { PIMAGEHLP_SYMBOL pSym; STACKFRAME sf; HANDLE process, thread; DWORD dwModBase, Disp, dwModAddrToPrint; BOOL more = FALSE; int count = 0; char modname[MAX_PATH]; process = GetCurrentProcess(); if(threadName) PRINT("Stacktrace (%s):", threadName); else PRINT("Stacktrace:"); bool suspended = false; CONTEXT c; if (e) { c = *e->ContextRecord; thread = GetCurrentThread(); } else { SuspendThread(hThread); suspended = true; memset(&c, 0, sizeof(CONTEXT)); c.ContextFlags = CONTEXT_FULL; // FIXME: This does not work if you want to dump the current thread's stack if (!GetThreadContext(hThread, &c)) { ResumeThread(hThread); return; } thread = hThread; } ZeroMemory(&sf, sizeof(sf)); sf.AddrPC.Offset = c.Eip; sf.AddrStack.Offset = c.Esp; sf.AddrFrame.Offset = c.Ebp; sf.AddrPC.Mode = AddrModeFlat; sf.AddrStack.Mode = AddrModeFlat; sf.AddrFrame.Mode = AddrModeFlat; // use globalalloc to reduce risk for allocator related deadlock pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384); char* printstrings = (char*)GlobalAlloc(GMEM_FIXED, 0); bool containsOglDll = false; while (true) { more = StackWalk( IMAGE_FILE_MACHINE_I386, // TODO: fix this for 64 bit windows? process, thread, &sf, &c, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL ); if (!more || sf.AddrFrame.Offset == 0 || count > MAX_STACK_DEPTH) { break; } dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset); if (dwModBase) { GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH); } else { strcpy(modname, "Unknown"); } pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); pSym->MaxNameLength = MAX_PATH; char* printstringsnew = (char*) GlobalAlloc(GMEM_FIXED, (count + 1) * BUFFER_SIZE); memcpy(printstringsnew, printstrings, count * BUFFER_SIZE); GlobalFree(printstrings); printstrings = printstringsnew; if (SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym)) { // This is the code path taken on VC if debugging syms are found. SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s(%s+%#0lx) [0x%08lX]", count, modname, pSym->Name, Disp, sf.AddrPC.Offset); } else { // This is the code path taken on MinGW, and VC if no debugging syms are found. if (strstr(modname, ".exe")) { // for the .exe, we need the absolute address dwModAddrToPrint = sf.AddrPC.Offset; } else { // for DLLs, we need the module-internal/relative address dwModAddrToPrint = sf.AddrPC.Offset - dwModBase; } SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s [0x%08lX]", count, modname, dwModAddrToPrint); } // OpenGL lib names (ATI): "atioglxx.dll" "atioglx2.dll" containsOglDll = containsOglDll || strstr(modname, "atiogl"); // OpenGL lib names (Nvidia): "nvoglnt.dll" "nvoglv32.dll" "nvoglv64.dll" (last one is a guess) containsOglDll = containsOglDll || strstr(modname, "nvogl"); // OpenGL lib names (Intel): "ig4dev32.dll" "ig4dev64.dll" containsOglDll = containsOglDll || strstr(modname, "ig4dev"); ++count; } if (suspended) { ResumeThread(hThread); } if (containsOglDll) { PRINT("This stack trace indicates a problem with your graphic card driver. " "Please try upgrading or downgrading it. " "Specifically recommended is the latest driver, and one that is as old as your graphic card. " "Make sure to use a driver removal utility, before installing other drivers."); } for (int i = 0; i < count; ++i) { PRINT("%s", printstrings + i * BUFFER_SIZE); } GlobalFree(printstrings); GlobalFree(pSym); }
/* ================ Sys_PrintStackTrace Occurs when we encounter a fatal error. Prints the stack trace as well as some other data. ================ */ LONG WINAPI Sys_PrintStackTrace(EXCEPTION_POINTERS* exception) { STACKFRAME frame = {}; #ifdef WIN32 DWORD machine = IMAGE_FILE_MACHINE_I386; #else DWORD machine = IMAGE_FILE_MACHINE_AMD64; #endif HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); int i = 0; frame.AddrPC.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; #ifdef WIN32 frame.AddrPC.Offset = exception->ContextRecord->Eip; frame.AddrFrame.Offset = exception->ContextRecord->Ebp; frame.AddrStack.Offset = exception->ContextRecord->Esp; #else frame.AddrPC.Offset = exception->ContextRecord->Rip; frame.AddrFrame.Offset = exception->ContextRecord->Rbp; frame.AddrStack.Offset = exception->ContextRecord->Rsp; #endif Com_Printf("------------------------\n"); Com_Printf("Enumerate Modules:\n"); Com_Printf("------------------------\n"); SymRefreshModuleList(process); SymEnumerateModules(process, Sys_PrintModule, nullptr); Com_Printf("\n\n"); Com_Printf("------------------------\n"); Com_Printf("Stack trace : \n"); Com_Printf("------------------------\n"); while (StackWalk(machine, process, thread, &frame, exception->ContextRecord, nullptr, SymFunctionTableAccess, SymGetModuleBase, nullptr)) { DWORD moduleBase = SymGetModuleBase(process, frame.AddrPC.Offset); char moduleName[MAX_PATH]; char funcName[MAX_PATH]; char fileName[MAX_PATH]; DWORD address = frame.AddrPC.Offset; char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 255]; PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL)symbolBuffer; IMAGEHLP_LINE line; DWORD offset = 0; line.SizeOfStruct = sizeof(IMAGEHLP_LINE); symbol->SizeOfStruct = (sizeof IMAGEHLP_SYMBOL) + 255; symbol->MaxNameLength = 254; if (moduleBase && GetModuleFileNameA((HINSTANCE)moduleBase, moduleName, MAX_PATH)) { Sys_CleanModuleName(moduleName, MAX_PATH); } else { moduleName[0] = '\0'; } if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &offset, symbol)) { Q_strncpyz(funcName, symbol->Name, MAX_PATH); } else { funcName[0] = '\0'; } if (SymGetLineFromAddr(process, frame.AddrPC.Offset, &offset, &line)) { Q_strncpyz(fileName, line.FileName, MAX_PATH); Sys_CleanModuleName(fileName, MAX_PATH); Com_sprintf(fileName, MAX_PATH, "%s:%i", fileName, line.LineNumber); } else { fileName[0] = '\0'; } Com_Printf("%03i %20s 0x%08X | %s (%s)\n", i, moduleName, address, funcName, fileName); i++; } Sys_Error("Unhanded Exception: 0x%08X", exception->ExceptionRecord->ExceptionCode); #ifdef _DEBUG return EXCEPTION_CONTINUE_SEARCH; #else return EXCEPTION_EXECUTE_HANDLER; #endif }
static void JKG_WriteStackCrawl( fileHandle_t *f, DWORD *stackCrawl ) { int i, dmod, gotsource, sourcedisp; HANDLE proc, thread; IMAGEHLP_LINE line; DWORD disp; char ModName[260]; static char SymPath[4096]; static char basepath[260]; static char fspath[260]; PIMAGEHLP_SYMBOL sym = (PIMAGEHLP_SYMBOL)malloc(1024); proc = GetCurrentProcess(); thread = GetCurrentThread(); SymPath[0] = 0; basepath[0] = 0; fspath[0] = 0; InitSymbolPath(SymPath, NULL); SymInitialize(proc, SymPath, TRUE); memset(sym, 0, 1024); sym->MaxNameLength = 800; sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); for(i = 0; i < MAX_JKG_ASSERT_STACK_CRAWL; i++) { if(stackCrawl[i] == 0) continue; // Grab the base address of the module that's the problem atm dmod = SymGetModuleBase(proc, stackCrawl[i]); if (!dmod) { strcpy(ModName,"Unknown"); } else { GetModuleBaseName(proc,(HMODULE)dmod, ModName, 260); } if (SymGetLineFromAddr(proc, stackCrawl[i], (PDWORD)&sourcedisp, &line)) { gotsource = 1; } else { gotsource = 0; } if (SymGetSymFromAddr(proc, stackCrawl[i], &disp, sym)) { if (gotsource) { JKG_WriteToAssertLogEasy(va("%s::%s(+0x%X) [0x%08X] - (%s:%i)\r\n", ModName, sym->Name, disp, stackCrawl[i], line.FileName, line.LineNumber), f); } else { JKG_WriteToAssertLogEasy(va("%s::%s(+0x%X) [0x%08X]\r\n", ModName, sym->Name, disp, stackCrawl[i]), f); } } else { if (gotsource) { // Not likely... JKG_WriteToAssertLogEasy(va("%s [0x%08X] - (%s:%i)\r\n", ModName, stackCrawl[i], line.FileName, line.LineNumber), f); } else { JKG_WriteToAssertLogEasy(va("%s [0x%08X]\r\n", ModName, stackCrawl[i]), f); } } } free(sym); JKG_WriteToAssertLogEasy("\r\n", f); }
void DumpStackStak(HANDLE hLogFile, PEXCEPTION_POINTERS lpExcetion) { STACKFRAME stackFrame; #ifdef _X86_ stackFrame.AddrPC.Offset = lpExcetion->ContextRecord->Eip; stackFrame.AddrPC.Mode = AddrModeFlat; stackFrame.AddrStack.Offset = lpExcetion->ContextRecord->Esp; stackFrame.AddrStack.Mode = AddrModeFlat; stackFrame.AddrFrame.Offset = lpExcetion->ContextRecord->Ebp; stackFrame.AddrFrame.Mode = AddrModeFlat; #else stackFrame.AddrPC.Offset = (DWORD)lpExcetion->ContextRecord->Fir ; stackFrame.AddrPC.Mode = AddrModeFlat ; stackFrame.AddrReturn.Offset = (DWORD)lpExcetion->ContextRecord->IntRa; stackFrame.AddrReturn.Mode = AddrModeFlat ; stackFrame.AddrStack.Offset = (DWORD)lpExcetion->ContextRecord->IntSp; stackFrame.AddrStack.Mode = AddrModeFlat ; stackFrame.AddrFrame.Offset = (DWORD)lpExcetion->ContextRecord->IntFp; stackFrame.AddrFrame.Mode = AddrModeFlat ; #endif //set up symbol engine DWORD dwOpts = SymGetOptions(); SymSetOptions(dwOpts|SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES); SymInitialize(GetCurrentProcess(), NULL, TRUE); #ifdef _WIN64 #define CH_MACHINE IMAGE_FILE_MACHINE_IA64 #else #define CH_MACHINE IMAGE_FILE_MACHINE_I386 #endif WriteLogFile(hLogFile, "\r\n\r\nStack trace list:\r\n"); do { BOOL bRet = StackWalk(CH_MACHINE, GetCurrentProcess(), GetCurrentThread(), &stackFrame, lpExcetion->ContextRecord, (PREAD_PROCESS_MEMORY_ROUTINE)ReadProcessMemory, SymFunctionTableAccess, SymGetModuleBase, NULL); if (bRet == FALSE || stackFrame.AddrFrame.Offset == 0) break; DWORD dwModuleBase = SymGetModuleBase(GetCurrentProcess(), stackFrame.AddrPC.Offset); if (dwModuleBase == 0) break; //module name of call TCHAR szModuleName[MAX_PATH] = {0}; GetModuleFileName((HMODULE)dwModuleBase, szModuleName, MAX_PATH); //funtion name DWORD dwDisp = 0; TCHAR szFuntionName[MAX_PATH+sizeof(IMAGEHLP_SYMBOL)] = {0}; PIMAGEHLP_SYMBOL lpSymb = (PIMAGEHLP_SYMBOL)szFuntionName; lpSymb->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); lpSymb->MaxNameLength = MAX_PATH; SymGetSymFromAddr(GetCurrentProcess(), stackFrame.AddrPC.Offset, &dwDisp, lpSymb); //line number and filename IMAGEHLP_LINE hlpLine; SymGetLineFromAddr(GetCurrentProcess(), (DWORD)stackFrame.AddrPC.Offset, &dwDisp, &hlpLine); WriteLogFile(hLogFile, "%s-%s %s::%d\r\n", lpSymb->Name, GetFilePart(szModuleName), hlpLine.FileName, hlpLine.LineNumber); } while (1); }
virtual int getStack(int depth, Backtrace::StackFrame* frames) { QMutexLocker locker(&m_mutex); char procname[MAX_PATH]; GetModuleFileNameA(NULL, procname, sizeof procname); CONTEXT context; memset(&context, 0, sizeof(CONTEXT)); context.ContextFlags = CONTEXT_FULL; HANDLE thread = GetCurrentThread(); bool success = GetThreadContext(thread, &context); if (!success) { return 0; } STACKFRAME frame; memset(&frame,0,sizeof(frame)); frame.AddrPC.Offset = context.Eip; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Offset = context.Esp; frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Offset = context.Ebp; frame.AddrFrame.Mode = AddrModeFlat; HANDLE process = GetCurrentProcess(); int i = 0; int skip = 2; const int SYMBUF = 512; char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + SYMBUF]; char module_name_raw[MAX_PATH]; while(StackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &frame, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0)) { if (skip-- > 0) { continue; } DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset); GetModuleFileNameA((HINSTANCE)module_base, module_name_raw, MAX_PATH); IMAGEHLP_SYMBOL* symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(symbol_buffer); symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); symbol->MaxNameLength = SYMBUF-1; DWORD dummy = 0; if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol)) { frames[i].function = symbol->Name; } else { frames[i].function.clear(); } frames[i].addr = reinterpret_cast<void*>(frame.AddrPC.Offset); frames[i].imageFile = module_name_raw; i++; if (i >= depth) break; } return i; }
/*********************************************************************** * SymGetModuleBase64 (DBGHELP.@) */ DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr) { if (!validate_addr64(dwAddr)) return 0; return SymGetModuleBase(hProcess, (DWORD)dwAddr); }
static void StackTracer(CONTEXT *pCtx, char *pMessage, int MaxFrames) { #if !defined(_WIN32_WCE) CONTEXT Ctx; STACKFRAME Stk; #ifdef _M_AMD64 DWORD64 symDisplacement,dwInstance; #else DWORD symDisplacement,dwInstance; #endif HANDLE hProcess = GetCurrentProcess(); int nFrames; char Path[MAX_PATH]; static BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + 512 ]; Printf(pMessage,"Stack Trace:\n"); // initialise IMAGEHLP SymInitialize(hProcess,NULL,TRUE); // init the argument contexts. memset(&Stk,0,sizeof(STACKFRAME)); memset(&Ctx,0,sizeof(CONTEXT)); // funny - if I copy the struct wholesale I get crashes... #ifdef _M_AMD64 Ctx.Rsp = pCtx->Rsp; Ctx.Rbp = pCtx->Rbp; Ctx.Rip = pCtx->Rip; Stk.AddrStack.Offset = pCtx->Rsp; Stk.AddrStack.Mode = AddrModeFlat; Stk.AddrFrame.Offset = pCtx->Rbp; Stk.AddrFrame.Mode = AddrModeFlat; Stk.AddrPC.Offset = pCtx->Rip; Stk.AddrPC.Mode = AddrModeFlat; #else Ctx.Esp = pCtx->Esp; Ctx.Ebp = pCtx->Ebp; Ctx.Eip = pCtx->Eip; Stk.AddrStack.Offset = pCtx->Esp; Stk.AddrStack.Mode = AddrModeFlat; Stk.AddrFrame.Offset = pCtx->Ebp; Stk.AddrFrame.Mode = AddrModeFlat; Stk.AddrPC.Offset = pCtx->Eip; Stk.AddrPC.Mode = AddrModeFlat; #endif // run the loop. Just that. for(nFrames = 0; StackWalk(IMAGE_FILE_MACHINE_I386,hProcess, NULL,&Stk,&Ctx, (PREAD_PROCESS_MEMORY_ROUTINE)ReadProcessMemory, (PFUNCTION_TABLE_ACCESS_ROUTINE)SymFunctionTableAccess, SymGetModuleBase,NULL) && (nFrames < MaxFrames);nFrames++) { PIMAGEHLP_SYMBOL pSymbol; dwInstance = SymGetModuleBase(hProcess,Stk.AddrPC.Offset); // invalid address - no module covers it. if (!dwInstance) continue; // get name of dll. No Module - no valid frame. if (!GetModuleFileNameA((HINSTANCE)dwInstance,Path,sizeof(Path))) continue; // get the symbol name pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer; pSymbol->MaxNameLength = sizeof(symbolBuffer)-sizeof(PIMAGEHLP_SYMBOL); if (SymGetSymFromAddr(GetCurrentProcess(), Stk.AddrPC.Offset, &symDisplacement, pSymbol)) Printf(pMessage,"Function: %s\n",pSymbol->Name+1); else Printf(pMessage,"Function: <NOSYMBOL>\n"); // show the header line Printf(pMessage,"File: %s\nRVA: %8.8X HINSTANCE: %8.8X BP: %8.8X\n", Path,Stk.AddrPC.Offset - dwInstance, dwInstance,Stk.AddrFrame.Offset); MemoryDump((void*)Stk.AddrPC.Offset, pMessage, 32); nFrames ++; Printf(pMessage,"\n"); } SymCleanup(GetCurrentProcess()); #endif }