summaryrefslogtreecommitdiff
path: root/mysys/stacktrace.c
diff options
context:
space:
mode:
authorVladislav Vaintroub <vvaintroub@mysql.com>2008-09-15 17:11:41 +0200
committerVladislav Vaintroub <vvaintroub@mysql.com>2008-09-15 17:11:41 +0200
commit26c48a80896acfb78340787fd4126504b29d6efc (patch)
tree4d374f2a20dfc95d7fe3a144d60429696cc9c76c /mysys/stacktrace.c
parent94fad7c0c242a15dd90be9fe061d0661a0fedd16 (diff)
parent5343b7ae5980fff72d82c3be44921e16e6471e9d (diff)
downloadmariadb-git-26c48a80896acfb78340787fd4126504b29d6efc.tar.gz
merge fix for 35987
Diffstat (limited to 'mysys/stacktrace.c')
-rw-r--r--mysys/stacktrace.c62
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;