Bug#35987 - crash report on windows doesn't resolve stack traces.
The problem here is that symbols can not be loaded, because symbol path is not set and default path does not include the directory where PDB is located. The problem is _not_ reproducible on the same machine where mysqld.exe is built - if PDB is not found in the symbol path, dbghelp would fallback to fully qualified PDB path as given in the executable header and on the build host this will succeed. The solution is to calculate symbol path and pass it to SymInitialize() call.
This commit is contained in:
parent
cafa5594d3
commit
5343b7ae59
@ -261,6 +261,7 @@ void write_core(int sig)
|
|||||||
#else /* __WIN__*/
|
#else /* __WIN__*/
|
||||||
|
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
|
Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
|
||||||
@ -349,6 +350,63 @@ void set_exception_pointers(EXCEPTION_POINTERS *ep)
|
|||||||
exception_ptrs = 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*/
|
/* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/
|
||||||
#ifndef SYMOPT_NO_PROMPTS
|
#ifndef SYMOPT_NO_PROMPTS
|
||||||
#define SYMOPT_NO_PROMPTS 0
|
#define SYMOPT_NO_PROMPTS 0
|
||||||
@ -365,6 +423,7 @@ void print_stacktrace(gptr unused1, ulong unused2)
|
|||||||
int i;
|
int i;
|
||||||
CONTEXT context;
|
CONTEXT context;
|
||||||
STACKFRAME64 frame={0};
|
STACKFRAME64 frame={0};
|
||||||
|
static char symbol_path[MAX_SYMBOL_PATH+1];
|
||||||
|
|
||||||
if(!exception_ptrs || !init_dbghelp_functions())
|
if(!exception_ptrs || !init_dbghelp_functions())
|
||||||
return;
|
return;
|
||||||
@ -373,7 +432,8 @@ void print_stacktrace(gptr unused1, ulong unused2)
|
|||||||
context = *(exception_ptrs->ContextRecord);
|
context = *(exception_ptrs->ContextRecord);
|
||||||
/*Initialize symbols.*/
|
/*Initialize symbols.*/
|
||||||
pSymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
|
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*/
|
/*Prepare stackframe for the first StackWalk64 call*/
|
||||||
frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
|
frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user