diff options
author | Vladislav Vaintroub <vvaintroub@mysql.com> | 2008-09-15 17:11:41 +0200 |
---|---|---|
committer | Vladislav Vaintroub <vvaintroub@mysql.com> | 2008-09-15 17:11:41 +0200 |
commit | 26c48a80896acfb78340787fd4126504b29d6efc (patch) | |
tree | 4d374f2a20dfc95d7fe3a144d60429696cc9c76c /mysys/stacktrace.c | |
parent | 94fad7c0c242a15dd90be9fe061d0661a0fedd16 (diff) | |
parent | 5343b7ae5980fff72d82c3be44921e16e6471e9d (diff) | |
download | mariadb-git-26c48a80896acfb78340787fd4126504b29d6efc.tar.gz |
merge fix for 35987
Diffstat (limited to 'mysys/stacktrace.c')
-rw-r--r-- | mysys/stacktrace.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 5b941bbd7d6..91f13d316e6 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -317,6 +317,7 @@ void my_write_core(int sig) #else /* __WIN__*/ #include <dbghelp.h> +#include <tlhelp32.h> /* Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll) @@ -409,6 +410,63 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep) exception_ptrs = ep; } + +/* + Get symbol path - semicolon-separated list of directories to search for debug + symbols. We expect PDB in the same directory as corresponding exe or dll, + so the path is build from directories of the loaded modules. If environment + variable _NT_SYMBOL_PATH is set, it's value appended to the symbol search path +*/ +static void get_symbol_path(char *path, size_t size) +{ + HANDLE hSnap; + char *envvar; + + path[0]= '\0'; + /* + Enumerate all modules, and add their directories to the path. + Avoid duplicate entries. + */ + hSnap= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); + if (hSnap != INVALID_HANDLE_VALUE) + { + BOOL ret; + MODULEENTRY32 mod; + mod.dwSize= sizeof(MODULEENTRY32); + for (ret= Module32First(hSnap, &mod); ret; ret= Module32Next(hSnap, &mod)) + { + char *module_dir= mod.szExePath; + char *p= strrchr(module_dir,'\\'); + if (!p) + { + /* + Path separator was not found. Not known to happen, if ever happens, + will indicate current directory. + */ + module_dir[0]= '.'; + p= module_dir + 1; + } + *p++= ';'; + *p= '\0'; + + if (!strstr(path, module_dir)) + { + strncat(path, module_dir, size); + } + } + CloseHandle(hSnap); + } + + /* Add _NT_SYMBOL_PATH, if present. */ + envvar= getenv("_NT_SYMBOL_PATH"); + if(envvar) + { + strncat(path, envvar, size); + } +} + +#define MAX_SYMBOL_PATH 32768 + /* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/ #ifndef SYMOPT_NO_PROMPTS #define SYMOPT_NO_PROMPTS 0 @@ -425,6 +483,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) int i; CONTEXT context; STACKFRAME64 frame={0}; + static char symbol_path[MAX_SYMBOL_PATH+1]; if(!exception_ptrs || !init_dbghelp_functions()) return; @@ -433,7 +492,8 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) context = *(exception_ptrs->ContextRecord); /*Initialize symbols.*/ pSymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG); - pSymInitialize(hProcess,NULL,TRUE); + get_symbol_path(symbol_path, MAX_SYMBOL_PATH); + pSymInitialize(hProcess, symbol_path, TRUE); /*Prepare stackframe for the first StackWalk64 call*/ frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat; |