43 #define NCBI_USE_ERRCODE_X Corelib_Stack
49 #define lenof(a) (sizeof(a) / sizeof((a)[0]))
50 #define MAXNAMELEN 1024
51 #define IMGSYMLEN (sizeof IMAGEHLP_SYMBOL64)
52 #define TTBUFLEN 65535
86 typedef DWORD (__stdcall *FGetModuleFileNameEx)(
HANDLE hProcess,
91 typedef DWORD (__stdcall *FGetModuleBaseName)(
HANDLE hProcess,
96 typedef BOOL (__stdcall *FGetModuleInformation)(
HANDLE hProcess,
102 FGetModuleFileNameEx GetModuleFileNameEx;
103 FGetModuleBaseName GetModuleBaseName;
104 FGetModuleInformation GetModuleInformation;
111 &EnumProcessModules);
112 GetModuleFileNameEx =
114 &GetModuleFileNameEx);
118 GetModuleInformation =
120 &GetModuleInformation);
122 if ( !EnumProcessModules ||
123 !GetModuleFileNameEx ||
124 !GetModuleBaseName ||
125 !GetModuleInformation ) {
129 vector<HMODULE> modules;
130 modules.resize(4096);
134 if ( !EnumProcessModules(hProcess,
136 DWORD(modules.size()*
sizeof(HMODULE)),
139 "EnumProcessModules() failed");
142 if ( needed > modules.size() *
sizeof(HMODULE)) {
144 string(
"More than ") +
149 needed /=
sizeof(HMODULE);
150 for (
size_t i = 0;
i < needed; ++
i) {
154 GetModuleInformation(hProcess, modules[
i], &mi,
sizeof(mi));
163 GetModuleFileNameEx(hProcess, modules[
i], tt,
sizeof(tt));
168 GetModuleBaseName(hProcess, modules[
i], tt,
sizeof(tt));
176 catch (exception& e) {
210 HANDLE curr_proc = GetCurrentProcess();
216 if (GetModuleFileNameA(0,
const_cast<char*
>(
tmp.data()),
218 string::size_type pos =
tmp.find_last_of(
"\\/");
219 if (pos != string::npos) {
222 search_path =
tmp +
';' + search_path;
225 const char* ptr = getenv(
"_NT_SYMBOL_PATH");
228 search_path =
tmp +
';' + search_path;
230 ptr = getenv(
"_NT_ALTERNATE_SYMBOL_PATH");
233 search_path =
tmp +
';' + search_path;
235 ptr = getenv(
"SYSTEMROOT");
238 search_path =
tmp +
';' + search_path;
242 if ( !SymInitialize(curr_proc,
243 const_cast<char*
>(search_path.c_str()),
249 DWORD symOptions = SymGetOptions();
250 symOptions &= ~SYMOPT_UNDNAME;
251 symOptions |= SYMOPT_LOAD_LINES;
252 SymSetOptions(symOptions);
257 catch (exception& e) {
263 <<
"Unknown error initializing symbols for stack trace.");
270 SymCleanup(GetCurrentProcess());
277 DWORD pid = GetCurrentProcessId();
291 DWORD64 module_addr = SymLoadModule64(
proc, 0,
292 const_cast<char*
>(it->imageName.c_str()),
293 const_cast<char*
>(it->moduleName.c_str()),
294 it->baseAddress, it->size);
295 if ( !module_addr ) {
299 _TRACE(
"Loaded symbols from " << it->moduleName);
329 HANDLE curr_proc = GetCurrentProcess();
330 HANDLE thread = GetCurrentThread();
333 DWORD img_type = IMAGE_FILE_MACHINE_AMD64;
337 RtlCaptureContext(&c);
341 memset(&s, 0,
sizeof s);
342 s.AddrPC.Offset = c.Rip;
343 s.AddrPC.Mode = AddrModeFlat;
344 s.AddrFrame.Offset = c.Rbp;
345 s.AddrFrame.Mode = AddrModeFlat;
346 s.AddrStack.Offset = c.Rsp;
347 s.AddrStack.Mode = AddrModeFlat;
351 for (
size_t frame = 0; frame <= max_depth; ++frame) {
353 if ( !StackWalk64(img_type, curr_proc, thread, &s, &c,
NULL,
354 SymFunctionTableAccess64,
366 if ( !s.AddrPC.Offset || !s.AddrReturn.Offset ) {
369 if (s.AddrPC.Offset == s.AddrReturn.Offset) {
376 catch (exception& e) {
398 HANDLE curr_proc = GetCurrentProcess();
400 IMAGEHLP_SYMBOL64 *pSym =
NULL;
406 IMAGEHLP_LINE64
Line;
420 sf_info.func =
"<cannot get function name for this address>";
422 if ( !SymGetSymFromAddr64(curr_proc, it->AddrPC.Offset, &offs64, pSym) ) {
428 sf_info.offs = offs64;
435 UnDecorateSymbolName(pSym->Name, undFullName,
438 sf_info.func = undFullName;
441 if (SymGetLineFromAddr(curr_proc,
445 sf_info.file =
Line.FileName;
446 sf_info.line =
Line.LineNumber;
448 _TRACE(
"failed to get line number for " << sf_info.func);
452 if ( !SymGetModuleInfo(curr_proc,
459 sf_info.module =
Module.ModuleName;
460 sf_info.module +=
"[";
461 sf_info.module +=
Module.ImageName;
462 sf_info.module +=
"]";
465 stack.push_back(sf_info);
468 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.
void Info(CExceptionArgs_Base &args)
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 Int8ToString(Int8 value, TNumToStringFlags flags=0, int base=10)
Convert Int8 to string.
#define HANDLE
An abstraction for a file handle.
Definition of all error codes used in corelib (xncbi.lib).
BOOL(WINAPI * FEnumProcessModules)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
Static variables safety - create on demand, destroy on application termination.
vector< SModuleEntry > TModules
struct _MODULEINFO MODULEINFO
vector< SModuleEntry > TModules
static bool s_FillModuleListPSAPI(TModules &mods, DWORD pid, HANDLE hProcess)
static bool s_FillModuleList(TModules &modules, DWORD pid, HANDLE hProcess)
static CSafeStaticPtr< CSymbolGuard > s_SymbolGuard
struct _MODULEINFO * LPMODULEINFO
TModules::iterator ModuleListIter
Define class Dll and for Portable DLL handling.
Structure for holding stack trace data.