Commit 1134fe2f authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

Bug #52850: mysqld-debug.pdb doesn't match

mysqld-debug.exe in 5.5.3 on windows

Fix:

- Do not rename PDB, install mysqld.pdb matching 
mysqld-debug.exe into bin\debug subdirectory

- Stack tracing code will now additionally look in 
debug subdirectory of the application directory 
for debug symbols.

- Small cleanup in stacktracing code: link with 
dbghelp rather than load functions dynamically 
at runtime, since dbghelp.dll is always present.

- Install debug binaries with WiX

cmake/install_macros.cmake:
  Add optional COMPONENT and PDB_DESTINATION 
  to INSTALL_DEBUG_TARGET
mysys/stacktrace.c:
  If binary is build with DBUG, also look in debug subdirectory
  of  executable directory. Packaging will put some PDBs there
  (e.g bin\mysqld-debug.exe will have corresponding pdb in 
  bin\debug)
  
  Also some cleanup: do not load dbghelp dynamically, instead
  link with it. dbghelp is present on all Windows starting with 
  XP.
packaging/WiX/CPackWixConfig.cmake:
  Install debug binaries
sql/CMakeLists.txt:
  Do not rename PDB for mysqld-debug.exe, install it in debug subdirectory
parent a849e860
......@@ -250,7 +250,7 @@ SET(DEBUGBUILDDIR "${BINARY_PARENTDIR}/debug" CACHE INTERNAL "Directory of debug
FUNCTION(INSTALL_DEBUG_TARGET target)
CMAKE_PARSE_ARGUMENTS(ARG
"DESTINATION;RENAME"
"DESTINATION;RENAME;PDB_DESTINATION;COMPONENT"
""
${ARGN}
)
......@@ -269,6 +269,9 @@ FUNCTION(INSTALL_DEBUG_TARGET target)
ELSE()
STRING(REPLACE "${CMAKE_CFG_INTDIR}" "Debug" debug_target_location "${target_location}" )
ENDIF()
IF(NOT ARG_COMPONENT)
SET(ARG_COMPONENT DebugBinaries)
ENDIF()
# Define permissions
# For executable files
......@@ -305,19 +308,26 @@ FUNCTION(INSTALL_DEBUG_TARGET target)
${RENAME_PARAM}
${PERMISSIONS_${target_type}}
CONFIGURATIONS Release RelWithDebInfo
COMPONENT ${ARG_COMPONENT}
OPTIONAL)
IF(MSVC)
GET_FILENAME_COMPONENT(ext ${debug_target_location} EXT)
STRING(REPLACE "${ext}" ".pdb" debug_pdb_target_location "${debug_target_location}" )
IF(RENAME_PARAM)
IF (RENAME_PARAM)
IF(NOT ARG_PDB_DESTINATION)
STRING(REPLACE "${ext}" ".pdb" "${ARG_RENAME}" pdb_rename)
SET(PDB_RENAME_PARAM RENAME ${pdb_rename})
SET(PDB_RENAME_PARAM RENAME "${pdb_rename}")
ENDIF()
ENDIF()
IF(NOT ARG_PDB_DESTINATION)
SET(ARG_PDB_DESTINATION "${ARG_DESTINATION}")
ENDIF()
INSTALL(FILES ${debug_pdb_target_location}
DESTINATION ${ARG_DESTINATION}
${RPDB_RENAME_PARAM}
DESTINATION ${ARG_PDB_DESTINATION}
${PDB_RENAME_PARAM}
CONFIGURATIONS Release RelWithDebInfo
COMPONENT ${ARG_COMPONENT}
OPTIONAL)
ENDIF()
ENDFUNCTION()
......
......@@ -334,44 +334,9 @@ void my_write_core(int sig)
#include <dbghelp.h>
#include <tlhelp32.h>
/*
Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
We do not redistribute dbghelp and the one comes with older OS (up to Windows 2000)
is missing some important functions like functions StackWalk64 or MinidumpWriteDump.
Hence, we have to load functions at runtime using LoadLibrary/GetProcAddress.
*/
typedef DWORD (WINAPI *SymSetOptions_FctType)(DWORD dwOptions);
typedef BOOL (WINAPI *SymGetModuleInfo64_FctType)
(HANDLE,DWORD64,PIMAGEHLP_MODULE64) ;
typedef BOOL (WINAPI *SymGetSymFromAddr64_FctType)
(HANDLE,DWORD64,PDWORD64,PIMAGEHLP_SYMBOL64) ;
typedef BOOL (WINAPI *SymGetLineFromAddr64_FctType)
(HANDLE,DWORD64,PDWORD,PIMAGEHLP_LINE64);
typedef BOOL (WINAPI *SymInitialize_FctType)
(HANDLE,PSTR,BOOL);
typedef BOOL (WINAPI *StackWalk64_FctType)
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,PVOID,PREAD_PROCESS_MEMORY_ROUTINE64,
PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64 ,
PTRANSLATE_ADDRESS_ROUTINE64);
typedef BOOL (WINAPI *MiniDumpWriteDump_FctType)(
IN HANDLE hProcess,
IN DWORD ProcessId,
IN HANDLE hFile,
IN MINIDUMP_TYPE DumpType,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
);
static SymSetOptions_FctType pSymSetOptions;
static SymGetModuleInfo64_FctType pSymGetModuleInfo64;
static SymGetSymFromAddr64_FctType pSymGetSymFromAddr64;
static SymInitialize_FctType pSymInitialize;
static StackWalk64_FctType pStackWalk64;
static SymGetLineFromAddr64_FctType pSymGetLineFromAddr64;
static MiniDumpWriteDump_FctType pMiniDumpWriteDump;
#if _MSC_VER
#pragma comment(lib, "dbghelp")
#endif
static EXCEPTION_POINTERS *exception_ptrs;
......@@ -382,50 +347,24 @@ void my_init_stacktrace()
{
}
/*
Dynamically load dbghelp functions
*/
BOOL init_dbghelp_functions()
{
static BOOL first_time= TRUE;
static BOOL rc;
HMODULE hDbghlp;
if(first_time)
{
first_time= FALSE;
hDbghlp= LoadLibrary("dbghelp");
if(!hDbghlp)
{
rc= FALSE;
return rc;
}
pSymSetOptions= (SymSetOptions_FctType)
GetProcAddress(hDbghlp,"SymSetOptions");
pSymInitialize= (SymInitialize_FctType)
GetProcAddress(hDbghlp,"SymInitialize");
pSymGetModuleInfo64= (SymGetModuleInfo64_FctType)
GetProcAddress(hDbghlp,"SymGetModuleInfo64");
pSymGetLineFromAddr64= (SymGetLineFromAddr64_FctType)
GetProcAddress(hDbghlp,"SymGetLineFromAddr64");
pSymGetSymFromAddr64=(SymGetSymFromAddr64_FctType)
GetProcAddress(hDbghlp,"SymGetSymFromAddr64");
pStackWalk64= (StackWalk64_FctType)
GetProcAddress(hDbghlp,"StackWalk64");
pMiniDumpWriteDump = (MiniDumpWriteDump_FctType)
GetProcAddress(hDbghlp,"MiniDumpWriteDump");
rc = (BOOL)(pSymSetOptions && pSymInitialize && pSymGetModuleInfo64
&& pSymGetLineFromAddr64 && pSymGetSymFromAddr64 && pStackWalk64);
}
return rc;
}
void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
{
exception_ptrs = ep;
}
/*
Appends directory to symbol path.
*/
static void add_to_symbol_path(char *path, size_t path_buffer_size,
char *dir, size_t dir_buffer_size)
{
strcat_s(dir, dir_buffer_size, ";");
if (!strstr(path, dir))
{
strcat_s(path, path_buffer_size, dir);
}
}
/*
Get symbol path - semicolon-separated list of directories to search for debug
......@@ -437,8 +376,28 @@ static void get_symbol_path(char *path, size_t size)
{
HANDLE hSnap;
char *envvar;
char *p;
#ifndef DBUG_OFF
static char pdb_debug_dir[MAX_PATH + 7];
#endif
path[0]= '\0';
#ifndef DBUG_OFF
/*
Add "debug" subdirectory of the application directory, sometimes PDB will
placed here by installation.
*/
GetModuleFileName(NULL, pdb_debug_dir, MAX_PATH);
p= strrchr(pdb_debug_dir, '\\');
if(p)
{
*p= 0;
strcat_s(pdb_debug_dir, sizeof(pdb_debug_dir), "\\debug;");
add_to_symbol_path(path, size, pdb_debug_dir, sizeof(pdb_debug_dir));
}
#endif
/*
Enumerate all modules, and add their directories to the path.
Avoid duplicate entries.
......@@ -452,7 +411,7 @@ static void get_symbol_path(char *path, size_t size)
for (ret= Module32First(hSnap, &mod); ret; ret= Module32Next(hSnap, &mod))
{
char *module_dir= mod.szExePath;
char *p= strrchr(module_dir,'\\');
p= strrchr(module_dir,'\\');
if (!p)
{
/*
......@@ -460,29 +419,23 @@ static void get_symbol_path(char *path, size_t size)
will indicate current directory.
*/
module_dir[0]= '.';
p= module_dir + 1;
module_dir[1]= '\0';
}
*p++= ';';
*p= '\0';
if (!strstr(path, module_dir))
{
size_t dir_len = strlen(module_dir);
if (size > dir_len)
else
{
strncat(path, module_dir, size-1);
size -= dir_len;
}
*p= '\0';
}
add_to_symbol_path(path, size, module_dir,sizeof(mod.szExePath));
}
CloseHandle(hSnap);
}
/* Add _NT_SYMBOL_PATH, if present. */
envvar= getenv("_NT_SYMBOL_PATH");
if(envvar && size)
if(envvar)
{
strncat(path, envvar, size-1);
strcat_s(path, size, envvar);
}
}
......@@ -506,15 +459,15 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
STACKFRAME64 frame={0};
static char symbol_path[MAX_SYMBOL_PATH];
if(!exception_ptrs || !init_dbghelp_functions())
if(!exception_ptrs)
return;
/* Copy context, as stackwalking on original will unwind the stack */
context = *(exception_ptrs->ContextRecord);
/*Initialize symbols.*/
pSymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
get_symbol_path(symbol_path, sizeof(symbol_path));
pSymInitialize(hProcess, symbol_path, TRUE);
SymInitialize(hProcess, symbol_path, TRUE);
/*Prepare stackframe for the first StackWalk64 call*/
frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
......@@ -546,11 +499,11 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
BOOL have_symbol= FALSE;
BOOL have_source= FALSE;
if(!pStackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0))
if(!StackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0))
break;
addr= frame.AddrPC.Offset;
have_module= pSymGetModuleInfo64(hProcess,addr,&module);
have_module= SymGetModuleInfo64(hProcess,addr,&module);
#ifdef _M_IX86
if(!have_module)
{
......@@ -560,13 +513,13 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
happy, pretend passing the old structure.
*/
module.SizeOfStruct= MODULE64_SIZE_WINXP;
have_module= pSymGetModuleInfo64(hProcess, addr, &module);
have_module= SymGetModuleInfo64(hProcess, addr, &module);
}
#endif
have_symbol= pSymGetSymFromAddr64(hProcess, addr, &function_offset,
have_symbol= SymGetSymFromAddr64(hProcess, addr, &function_offset,
&(package.sym));
have_source= pSymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
have_source= SymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
fprintf(stderr, "%p ", addr);
if(have_module)
......@@ -610,7 +563,7 @@ void my_write_core(int unused)
MINIDUMP_EXCEPTION_INFORMATION info;
HANDLE hFile;
if(!exception_ptrs || !init_dbghelp_functions() || !pMiniDumpWriteDump)
if(!exception_ptrs)
return;
info.ExceptionPointers= exception_ptrs;
......@@ -628,7 +581,7 @@ void my_write_core(int unused)
if(hFile)
{
/* Create minidump */
if(pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
if(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, MiniDumpNormal, &info, 0, 0))
{
fprintf(stderr, "Minidump written to %s\n",
......
......@@ -7,7 +7,7 @@ IF(ESSENTIALS)
SET(CPACK_PACKAGE_FILE_NAME "mysql-essentials-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH}-win${bits}")
ELSE()
SET(CPACK_COMPONENTS_USED
"Server;Client;DataFiles;Development;SharedLibraries;Embedded;Debuginfo;Documentation;IniFiles;Readme;Server_Scripts")
"Server;Client;DataFiles;Development;SharedLibraries;Embedded;Debuginfo;Documentation;IniFiles;Readme;Server_Scripts;DebugBinaries")
ENDIF()
......@@ -45,6 +45,13 @@ SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_DESCRIPTION "Install MySQL Server")
SET(CPACK_COMPONENT_CLIENT_DISPLAY_NAME "Client Programs")
SET(CPACK_COMPONENT_CLIENT_DESCRIPTION
"Various helpful (commandline) tools including the mysql command line client" )
# Subfeature "Debug binaries"
SET(CPACK_COMPONENT_DEBUGBINARIES_GROUP "MySQLServer")
SET(CPACK_COMPONENT_DEBUGBINARIES_DISPLAY_NAME "Debug binaries")
SET(CPACK_COMPONENT_DEBUGBINARIES_DESCRIPTION
"Debug/trace versions of executables and libraries" )
#SET(CPACK_COMPONENT_DEBUGBINARIES_WIX_LEVEL 2)
#Subfeature "Data Files"
SET(CPACK_COMPONENT_DATAFILES_GROUP "MySQLServer")
......
......@@ -156,7 +156,10 @@ IF(WITH_MYSQLD_LDFLAGS)
SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS
"${MYSQLD_LINK_FLAGS} ${WITH_MYSQLD_LDFLAGS}")
ENDIF()
INSTALL_DEBUG_TARGET(mysqld DESTINATION ${INSTALL_SBINDIR} RENAME mysqld-debug)
INSTALL_DEBUG_TARGET(mysqld
DESTINATION ${INSTALL_SBINDIR}
PDB_DESTINATION ${INSTALL_SBINDIR}/debug
RENAME mysqld-debug)
# Handle out-of-source build from source package with possibly broken
# bison. Copy bison output to from source to build directory, if not already
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment