Hi, three comments marked with "magnus:" below.
Vladislav Vaintroub skrev:
> #At file:///G:/bzr/mysql-5.0-bugteam/
>
> 2678 Vladislav Vaintroub 2008-09-15
> 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.
> modified:
> sql/stacktrace.c
>
> === modified file 'sql/stacktrace.c'
> --- a/sql/stacktrace.c 2008-02-19 11:37:39 +0000
> +++ b/sql/stacktrace.c 2008-09-15 10:45:50 +0000
> @@ -261,6 +261,7 @@ void write_core(int sig)
> #else /* __WIN__*/
>
> #include <dbghelp.h>
> +#include <tlhelp32.h>
>
> /*
> Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
> @@ -349,6 +350,55 @@ void set_exception_pointers(EXCEPTION_PO
> 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;
magnus: Somewhere you should set "path[0]= '\0'" to cover the case wher
no modules and no envvar.
> +
> + /*
> + 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)
> + {
> + *p++= ';';
> + *p= 0;
> + }
magnus: if no \ is found, you will add the full module dir verbatim. But
what about ending semicolon ?
> + if (!strstr(path, module_dir))
> + {
> + strncat(path, size, module_dir);
magnus: ^ size should be last in 'strncat'
> + }
> + }
> + CloseHandle(hSnap);
> + }
> +
> + /* Add _NT_SYMBOL_PATH, if present. */
> + envvar= getenv("_NT_SYMBOL_PATH");
> + if(envvar)
> + {
> + strncat(path, envvar, size);
> + }
> +}
> +
> +#define MAX_SYMBOL_PATH 32768
magnus: quite big, but ok I guess.
> +
> /* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/
> #ifndef SYMOPT_NO_PROMPTS
> #define SYMOPT_NO_PROMPTS 0
> @@ -365,6 +415,7 @@ void print_stacktrace(gptr unused1, ulon
> int i;
> CONTEXT context;
> STACKFRAME64 frame={0};
> + static char symbol_path[MAX_SYMBOL_PATH+1];
>
> if(!exception_ptrs || !init_dbghelp_functions())
> return;
> @@ -373,7 +424,8 @@ void print_stacktrace(gptr unused1, ulon
> 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;
>
>