(__stdcall *FCreateToolhelp32Snapshot)(
WORDdwFlags,
104FCreateToolhelp32Snapshot CreateToolhelp32Snapshot;
109 const char*dllname[] = {
115 const char* libname = dllname[0];
116unique_ptr<CDll> dll;
120CreateToolhelp32Snapshot =
121dll->GetEntryPoint_Func(
"CreateToolhelp32Snapshot",
122&CreateToolhelp32Snapshot);
124dll->GetEntryPoint_Func(
"Module32First", &Module32First);
126dll->GetEntryPoint_Func(
"Module32Next", &Module32Next);
128 if(CreateToolhelp32Snapshot && Module32First && Module32Next) {
133 if( !CreateToolhelp32Snapshot ) {
135 "toolhelp32 functions not available");
139 if(handle == (
HANDLE) -1) {
141 "failed to create toolhelp32 snapshot");
146 bool done= !Module32First(handle, &me) ?
true:
false;
154modules.push_back(e);
156 done= !Module32Next(handle, &me) ?
true:
false;
161 returnmodules.size() != 0;
163 catch(exception& e) {
164 ERR_POST_X(1,
Error<<
"Error retrieving toolhelp32 symbols: "<< e.what());
167 ERR_POST_X(2,
Error<<
"Unknown error retrieving toolhelp32 symbols");
198 typedef DWORD(__stdcall *FGetModuleBaseNameA)(
HANDLEhProcess,
203 typedef BOOL(__stdcall *FGetModuleInformation)(
HANDLEhProcess,
210FGetModuleBaseNameA GetModuleBaseNameA;
211FGetModuleInformation GetModuleInformation;
218&EnumProcessModules);
219GetModuleFileNameExA =
221&GetModuleFileNameExA);
224&GetModuleBaseNameA);
225GetModuleInformation =
227&GetModuleInformation);
229 if( !EnumProcessModules ||
230!GetModuleFileNameExA ||
231!GetModuleBaseNameA ||
232!GetModuleInformation ) {
236vector<HMODULE> modules;
237modules.resize(4096);
241 if( !EnumProcessModules(hProcess,
243modules.size()*
sizeof(HMODULE),
246 "EnumProcessModules() failed");
249 if( needed > modules.size() *
sizeof(HMODULE)) {
251 string(
"More than ") +
256needed /=
sizeof(HMODULE);
257 for(
size_t i= 0;
i< needed; ++
i) {
261GetModuleInformation(hProcess, modules[
i], &mi,
sizeof(mi));
270GetModuleFileNameExA(hProcess, modules[
i], tt,
sizeof(tt));
275GetModuleBaseNameA(hProcess, modules[
i], tt,
sizeof(tt));
283 catch(exception& e) {
322 HANDLEcurr_proc = GetCurrentProcess();
328 if(GetModuleFileNameA(0,
const_cast<char*
>(
tmp.data()),
330string::size_type pos =
tmp.find_last_of(
"\\/");
331 if(pos != string::npos) {
334search_path =
tmp+
';'+ search_path;
337 const char* ptr = getenv(
"_NT_SYMBOL_PATH");
340search_path =
tmp+
';'+ search_path;
342ptr = getenv(
"_NT_ALTERNATE_SYMBOL_PATH");
345search_path =
tmp+
';'+ search_path;
347ptr = getenv(
"SYSTEMROOT");
350search_path =
tmp+
';'+ search_path;
354 if( !SymInitialize(curr_proc,
355 const_cast<char*
>(search_path.c_str()),
361 DWORDsymOptions = SymGetOptions();
362symOptions |= SYMOPT_LOAD_LINES;
363symOptions &= ~SYMOPT_UNDNAME;
364SymSetOptions(symOptions);
369 catch(exception& e) {
375<<
"Unknown error initializing symbols for stack trace.");
382SymCleanup(GetCurrentProcess());
389 DWORDpid = GetCurrentProcessId();
403 DWORDmodule_addr = SymLoadModule(
proc, 0,
404 const_cast<char*
>(it->imageName.c_str()),
405 const_cast<char*
>(it->moduleName.c_str()),
406it->baseAddress, it->size);
407 if( !module_addr ) {
411 _TRACE(
"Loaded symbols from "<< it->moduleName);
437 #define GET_CURRENT_CONTEXT(c, contextFlags) \ 439 memset(&c, 0, sizeof(CONTEXT)); \ 440 c.ContextFlags = contextFlags; \ 443 __asm mov c.Eip, eax \ 444 __asm mov c.Ebp, ebp \ 445 __asm mov c.Esp, esp \ 449 #pragma warning( push ) 450 #pragma warning( disable : 4748) 454 HANDLEcurr_proc = GetCurrentProcess();
455 HANDLEthread = GetCurrentThread();
458 DWORDimg_type = IMAGE_FILE_MACHINE_I386;
466memset(&s, 0,
sizeofs);
467s.AddrPC.Offset = c.Eip;
468s.AddrPC.Mode = AddrModeFlat;
469s.AddrFrame.Offset = c.Ebp;
470s.AddrFrame.Mode = AddrModeFlat;
471s.AddrStack.Offset = c.Esp;
472s.AddrStack.Mode = AddrModeFlat;
476 for(
size_tframe = 0; frame <= max_depth; ++frame) {
478 if( !StackWalk(img_type, curr_proc, thread, &s, &c,
NULL,
479SymFunctionTableAccess,
490 if( !s.AddrPC.Offset ) {
497 catch(exception& e) {
505 #pragma warning( pop ) 521 HANDLEcurr_proc = GetCurrentProcess();
523IMAGEHLP_SYMBOL *pSym =
NULL;
531 Line.SizeOfStruct =
sizeof(
Line);
542sf_info.func =
"<cannot get function name for this address>";
544 if( !SymGetSymFromAddr(curr_proc,
548stack.push_back(sf_info);
558UnDecorateSymbolName(pSym->Name, undFullName,
561sf_info.func = undFullName;
564 if(SymGetLineFromAddr(curr_proc,
568sf_info.file =
Line.FileName;
569sf_info.line =
Line.LineNumber;
571 _TRACE(
"failed to get line number for "<< sf_info.func);
575 if( !SymGetModuleInfo(curr_proc,
581sf_info.module =
Module.ModuleName;
582sf_info.module +=
"[";
583sf_info.module +=
Module.ImageName;
584sf_info.module +=
"]";
587stack.push_back(sf_info);
590 catch(exception& e) {
backward::StackTrace TStack
void Expand(CStackTrace::TStack &stack)
vector< TStackFrame > TStack
list< SStackFrameInfo > TStack
static unsigned int s_GetStackTraceMaxDepth(void)
set< string > TLoadedModules
iterator_bool insert(const value_type &val)
const_iterator find(const key_type &key) const
const_iterator end() const
parent_type::const_iterator const_iterator
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
TFunc GetEntryPoint_Func(const string &name, TFunc *func)
Get DLLs entry point (function).
void Error(CExceptionArgs_Base &args)
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
static string GetCwd(void)
Get the current working directory.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static string SizetToString(size_t value, TNumToStringFlags flags=0, int base=10)
Convert size_t to string.
#define HANDLE
An abstraction for a file handle.
Definition of all error codes used in corelib (xncbi.lib).
BOOL(WINAPI * FModule32Next)(HANDLE hSnapshot, LPMODULEENTRY32_A lpme)
BOOL(WINAPI * FEnumProcessModules)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
DWORD(WINAPI * FGetModuleFileNameExA)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize)
BOOL(WINAPI * FModule32First)(HANDLE hSnapshot, LPMODULEENTRY32_A lpme)
Static variables safety - create on demand, destroy on application termination.
struct _MODULEINFO MODULEINFO
vector< SModuleEntry > TModules
static bool s_FillModuleListPSAPI(TModules &mods, DWORD pid, HANDLE hProcess)
MODULEENTRY32 * LPMODULEENTRY32
static bool s_FillModuleListTH32(TModules &modules, DWORD pid)
MODULEENTRY32 * PMODULEENTRY32
#define TH32CS_SNAPMODULE
static CSafeStatic< CSymbolGuard > s_SymbolGuard
#define GET_CURRENT_CONTEXT(c, contextFlags)
static bool s_FillModuleList(TModules &modules, DWORD pid, HANDLE hProcess)
struct _MODULEINFO * LPMODULEINFO
struct tagMODULEENTRY32 MODULEENTRY32
TModules::iterator ModuleListIter
#define MAX_MODULE_NAME32
Define class Dll and for Portable DLL handling.
Structure for holding stack trace data.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4