Make wxMSW stack walking methods work with Unicode identifiers.
This allows to show the stack properly for e.g. Japanese programs. Closes #15138. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74817 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
39c0d6d6b6
commit
bf9ce7b55e
@ -589,6 +589,7 @@ wxMSW:
|
|||||||
- Fix launching some types of files under Windows 7 and later (Steven Houchins).
|
- Fix launching some types of files under Windows 7 and later (Steven Houchins).
|
||||||
- Don't use an icon for items inserted without one into wxListCtrl (Chuddah).
|
- Don't use an icon for items inserted without one into wxListCtrl (Chuddah).
|
||||||
- Handle custom configurations when using MSVC autolinking (tinman).
|
- Handle custom configurations when using MSVC autolinking (tinman).
|
||||||
|
- Fix wxStackWalker to work with Unicode identifiers (suzumizaki).
|
||||||
|
|
||||||
wxOSX:
|
wxOSX:
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Name: wx/msw/debughlp.h
|
// Name: wx/msw/debughlp.h
|
||||||
// Purpose: wraps dbghelp.h standard file
|
// Purpose: wraps dbghelp.h standard file
|
||||||
// Author: Vadim Zeitlin
|
// Author: Vadim Zeitlin
|
||||||
// Modified by:
|
// Modified by: Suzumizaki-kimitaka 2013-04-10
|
||||||
// Created: 2005-01-08 (extracted from msw/crashrpt.cpp)
|
// Created: 2005-01-08 (extracted from msw/crashrpt.cpp)
|
||||||
// Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
// Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
@ -42,6 +42,54 @@
|
|||||||
|
|
||||||
#if wxUSE_DBGHELP
|
#if wxUSE_DBGHELP
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
The table below shows which functions are exported by dbghelp.dll.
|
||||||
|
On 64 bit Windows, it looks no difference between 32bit dll and
|
||||||
|
64bit one.
|
||||||
|
Vista-64 and Win8-64 looks same, but in fact, "Ex" and "ExW"
|
||||||
|
versions are exist only in Windows 8.
|
||||||
|
|
||||||
|
Make sure SymGetLineFromAddrW and EnumerateLoadedModulesW DON'T
|
||||||
|
exists.
|
||||||
|
|
||||||
|
functions | Windows | XP-32 Vista-64 Win8-64
|
||||||
|
SymEnumSymbolsW n/a v v
|
||||||
|
SymFromAddrW n/a v v
|
||||||
|
SymInitializeW n/a v v
|
||||||
|
|
||||||
|
SymEnumSymbols v v v
|
||||||
|
SymFromAddr v v v
|
||||||
|
SymInitialize v v v
|
||||||
|
|
||||||
|
SymGetLineFromAddrW64 n/a v v
|
||||||
|
SymGetLineFromAddr64 v v v
|
||||||
|
SymGetLineFromAddrW n/a n/a n/a
|
||||||
|
SymGetLineFromAddr v v v
|
||||||
|
|
||||||
|
EnumerateLoadedModulesW64 n/a v v
|
||||||
|
EnumerateLoadedModules64 v v v
|
||||||
|
EnumerateLoadedModulesW n/a n/a n/a
|
||||||
|
EnumerateLoadedModules v v v
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define wxPENUMLOADED_MODULES_CALLBACK64 PENUMLOADED_MODULES_CALLBACKW64
|
||||||
|
#define wxPSYMBOL_INFO PSYMBOL_INFOW
|
||||||
|
#define wxSYMBOL_INFO SYMBOL_INFOW
|
||||||
|
#define wxPIMAGEHLP_LINE PIMAGEHLP_LINEW64
|
||||||
|
#define wxIMAGEHLP_LINE IMAGEHLP_LINEW64
|
||||||
|
#define wxPSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW
|
||||||
|
#else
|
||||||
|
#define wxPENUMLOADED_MODULES_CALLBACK64 PENUMLOADED_MODULES_CALLBACK64
|
||||||
|
#define wxPSYMBOL_INFO PSYMBOL_INFO
|
||||||
|
#define wxSYMBOL_INFO SYMBOL_INFO
|
||||||
|
#define wxPIMAGEHLP_LINE PIMAGEHLP_LINE64
|
||||||
|
#define wxIMAGEHLP_LINE IMAGEHLP_LINE64
|
||||||
|
#define wxPSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACK
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxDbgHelpDLL: dynamically load dbghelp.dll functions
|
// wxDbgHelpDLL: dynamically load dbghelp.dll functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -141,31 +189,47 @@ public:
|
|||||||
// function types
|
// function types
|
||||||
typedef DWORD (WINAPI *SymGetOptions_t)();
|
typedef DWORD (WINAPI *SymGetOptions_t)();
|
||||||
typedef DWORD (WINAPI *SymSetOptions_t)(DWORD);
|
typedef DWORD (WINAPI *SymSetOptions_t)(DWORD);
|
||||||
typedef BOOL (WINAPI *SymInitialize_t)(HANDLE, LPSTR, BOOL);
|
|
||||||
typedef BOOL (WINAPI *StackWalk_t)(DWORD, HANDLE, HANDLE, LPSTACKFRAME,
|
typedef BOOL (WINAPI *StackWalk_t)(DWORD, HANDLE, HANDLE, LPSTACKFRAME,
|
||||||
LPVOID, PREAD_PROCESS_MEMORY_ROUTINE,
|
LPVOID, PREAD_PROCESS_MEMORY_ROUTINE,
|
||||||
PFUNCTION_TABLE_ACCESS_ROUTINE,
|
PFUNCTION_TABLE_ACCESS_ROUTINE,
|
||||||
PGET_MODULE_BASE_ROUTINE,
|
PGET_MODULE_BASE_ROUTINE,
|
||||||
PTRANSLATE_ADDRESS_ROUTINE);
|
PTRANSLATE_ADDRESS_ROUTINE);
|
||||||
typedef BOOL (WINAPI *SymFromAddr_t)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
|
|
||||||
typedef LPVOID (WINAPI *SymFunctionTableAccess_t)(HANDLE, DWORD_PTR);
|
typedef LPVOID (WINAPI *SymFunctionTableAccess_t)(HANDLE, DWORD_PTR);
|
||||||
typedef DWORD_PTR (WINAPI *SymGetModuleBase_t)(HANDLE, DWORD_PTR);
|
typedef DWORD_PTR (WINAPI *SymGetModuleBase_t)(HANDLE, DWORD_PTR);
|
||||||
typedef BOOL (WINAPI *SymGetLineFromAddr_t)(HANDLE, DWORD_PTR,
|
|
||||||
PDWORD, PIMAGEHLP_LINE);
|
|
||||||
typedef BOOL (WINAPI *SymSetContext_t)(HANDLE, PIMAGEHLP_STACK_FRAME,
|
typedef BOOL (WINAPI *SymSetContext_t)(HANDLE, PIMAGEHLP_STACK_FRAME,
|
||||||
PIMAGEHLP_CONTEXT);
|
PIMAGEHLP_CONTEXT);
|
||||||
typedef BOOL (WINAPI *SymEnumSymbols_t)(HANDLE, ULONG64, PCSTR,
|
|
||||||
PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID);
|
|
||||||
typedef BOOL (WINAPI *SymGetTypeInfo_t)(HANDLE, DWORD64, ULONG,
|
typedef BOOL (WINAPI *SymGetTypeInfo_t)(HANDLE, DWORD64, ULONG,
|
||||||
IMAGEHLP_SYMBOL_TYPE_INFO, PVOID);
|
IMAGEHLP_SYMBOL_TYPE_INFO, PVOID);
|
||||||
typedef BOOL (WINAPI *SymCleanup_t)(HANDLE);
|
typedef BOOL (WINAPI *SymCleanup_t)(HANDLE);
|
||||||
typedef BOOL (WINAPI *EnumerateLoadedModules_t)(HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID);
|
|
||||||
typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
|
typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
|
||||||
MINIDUMP_TYPE,
|
MINIDUMP_TYPE,
|
||||||
CONST PMINIDUMP_EXCEPTION_INFORMATION,
|
CONST PMINIDUMP_EXCEPTION_INFORMATION,
|
||||||
CONST PMINIDUMP_USER_STREAM_INFORMATION,
|
CONST PMINIDUMP_USER_STREAM_INFORMATION,
|
||||||
CONST PMINIDUMP_CALLBACK_INFORMATION);
|
CONST PMINIDUMP_CALLBACK_INFORMATION);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *EnumerateLoadedModules_t)(HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID);
|
||||||
|
typedef BOOL (WINAPI *SymGetLineFromAddr_t)(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *EnumerateLoadedModules64_t)(HANDLE, PENUMLOADED_MODULES_CALLBACK64, PVOID);
|
||||||
|
typedef BOOL (WINAPI *SymInitialize_t)(HANDLE, LPCSTR, BOOL);
|
||||||
|
typedef BOOL (WINAPI *SymFromAddr_t)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
|
||||||
|
typedef BOOL (WINAPI *SymGetLineFromAddr64_t)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
|
||||||
|
typedef BOOL (WINAPI *SymEnumSymbols_t)(HANDLE, ULONG64, PCSTR,
|
||||||
|
PSYM_ENUMERATESYMBOLS_CALLBACK, const PVOID);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *EnumerateLoadedModulesW64_t)(HANDLE, PENUMLOADED_MODULES_CALLBACKW64, PVOID);
|
||||||
|
typedef BOOL (WINAPI *SymInitializeW_t)(HANDLE, LPCWSTR, BOOL);
|
||||||
|
typedef BOOL (WINAPI *SymFromAddrW_t)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFOW);
|
||||||
|
typedef BOOL (WINAPI *SymGetLineFromAddrW64_t)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINEW64);
|
||||||
|
typedef BOOL (WINAPI *SymEnumSymbolsW_t)(HANDLE, ULONG64, PCWSTR,
|
||||||
|
PSYM_ENUMERATESYMBOLS_CALLBACKW, const PVOID);
|
||||||
|
|
||||||
|
static BOOL EnumerateLoadedModulesT(HANDLE, wxPENUMLOADED_MODULES_CALLBACK64, PVOID);
|
||||||
|
static BOOL SymInitializeT(HANDLE, LPCTSTR, BOOL);
|
||||||
|
static BOOL SymFromAddrT(HANDLE, DWORD64, PDWORD64, wxPSYMBOL_INFO);
|
||||||
|
static BOOL SymGetLineFromAddrT(HANDLE, DWORD64, PDWORD, wxPIMAGEHLP_LINE);
|
||||||
|
static BOOL SymEnumSymbolsT(HANDLE, ULONG64, PCTSTR, wxPSYM_ENUMERATESYMBOLS_CALLBACK, const PVOID);
|
||||||
|
|
||||||
// The macro called by wxDO_FOR_ALL_SYM_FUNCS() below takes 2 arguments:
|
// The macro called by wxDO_FOR_ALL_SYM_FUNCS() below takes 2 arguments:
|
||||||
// the name of the function in the program code, which never has "64"
|
// the name of the function in the program code, which never has "64"
|
||||||
// suffix, and the name of the function in the DLL which can have "64"
|
// suffix, and the name of the function in the DLL which can have "64"
|
||||||
@ -174,7 +238,6 @@ public:
|
|||||||
#define wxSYM_CALL(what, name) what(name, name)
|
#define wxSYM_CALL(what, name) what(name, name)
|
||||||
#if defined(_M_AMD64)
|
#if defined(_M_AMD64)
|
||||||
#define wxSYM_CALL_64(what, name) what(name, name ## 64)
|
#define wxSYM_CALL_64(what, name) what(name, name ## 64)
|
||||||
|
|
||||||
// Also undo all the "helpful" definitions done by imagehlp.h that map 32
|
// Also undo all the "helpful" definitions done by imagehlp.h that map 32
|
||||||
// bit functions to 64 bit ones, we don't need this as we do it ourselves.
|
// bit functions to 64 bit ones, we don't need this as we do it ourselves.
|
||||||
#undef StackWalk
|
#undef StackWalk
|
||||||
@ -186,26 +249,56 @@ public:
|
|||||||
#define wxSYM_CALL_64(what, name) what(name, name)
|
#define wxSYM_CALL_64(what, name) what(name, name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define wxDO_FOR_ALL_SYM_FUNCS(what) \
|
#define wxSYM_CALL_ALWAYS_W(what, name) what(name ## W, name ## W)
|
||||||
wxSYM_CALL_64(what, StackWalk); \
|
|
||||||
wxSYM_CALL_64(what, SymFunctionTableAccess); \
|
#define wxSYM_CALL_ALTERNATIVES(what, name) \
|
||||||
wxSYM_CALL_64(what, SymGetModuleBase); \
|
what(name, name); \
|
||||||
wxSYM_CALL_64(what, SymGetLineFromAddr); \
|
what(name ## 64, name ## 64); \
|
||||||
wxSYM_CALL_64(what, EnumerateLoadedModules); \
|
what(name ## W64, name ## W64)
|
||||||
\
|
|
||||||
wxSYM_CALL(what, SymGetOptions); \
|
#define wxDO_FOR_ALL_SYM_FUNCS_REQUIRED_PUBLIC(what) \
|
||||||
wxSYM_CALL(what, SymSetOptions); \
|
wxSYM_CALL_64(what, StackWalk); \
|
||||||
wxSYM_CALL(what, SymInitialize); \
|
wxSYM_CALL_64(what, SymFunctionTableAccess); \
|
||||||
wxSYM_CALL(what, SymFromAddr); \
|
wxSYM_CALL_64(what, SymGetModuleBase); \
|
||||||
wxSYM_CALL(what, SymSetContext); \
|
\
|
||||||
wxSYM_CALL(what, SymEnumSymbols); \
|
wxSYM_CALL(what, SymGetOptions); \
|
||||||
wxSYM_CALL(what, SymGetTypeInfo); \
|
wxSYM_CALL(what, SymSetOptions); \
|
||||||
wxSYM_CALL(what, SymCleanup); \
|
wxSYM_CALL(what, SymSetContext); \
|
||||||
|
wxSYM_CALL(what, SymGetTypeInfo); \
|
||||||
|
wxSYM_CALL(what, SymCleanup); \
|
||||||
wxSYM_CALL(what, MiniDumpWriteDump)
|
wxSYM_CALL(what, MiniDumpWriteDump)
|
||||||
|
|
||||||
|
#define wxDO_FOR_ALL_SYM_FUNCS_REQUIRED_PRIVATE(what) \
|
||||||
|
wxSYM_CALL(what, SymInitialize); \
|
||||||
|
wxSYM_CALL(what, SymFromAddr); \
|
||||||
|
wxSYM_CALL(what, SymEnumSymbols)
|
||||||
|
|
||||||
|
#define wxDO_FOR_ALL_SYM_FUNCS_REQUIRED(what) \
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_REQUIRED_PRIVATE(what); \
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_REQUIRED_PUBLIC(what)
|
||||||
|
|
||||||
|
// Alternation will work when the following functions are not found,
|
||||||
|
// therefore they are not included in REQUIRED version.
|
||||||
|
#define wxDO_FOR_ALL_SYM_FUNCS_OPTIONAL(what) \
|
||||||
|
wxSYM_CALL_ALTERNATIVES(what, SymGetLineFromAddr); \
|
||||||
|
wxSYM_CALL_ALTERNATIVES(what, EnumerateLoadedModules); \
|
||||||
|
wxSYM_CALL_ALWAYS_W(what, SymInitialize); \
|
||||||
|
wxSYM_CALL_ALWAYS_W(what, SymFromAddr); \
|
||||||
|
wxSYM_CALL_ALWAYS_W(what, SymEnumSymbols)
|
||||||
|
|
||||||
|
#define wxDO_FOR_ALL_SYM_FUNCS(what) \
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_REQUIRED(what); \
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_OPTIONAL(what)
|
||||||
|
|
||||||
#define wxDECLARE_SYM_FUNCTION(func, name) static func ## _t func
|
#define wxDECLARE_SYM_FUNCTION(func, name) static func ## _t func
|
||||||
|
|
||||||
wxDO_FOR_ALL_SYM_FUNCS(wxDECLARE_SYM_FUNCTION);
|
wxDO_FOR_ALL_SYM_FUNCS_REQUIRED_PUBLIC(wxDECLARE_SYM_FUNCTION);
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_REQUIRED_PRIVATE(wxDECLARE_SYM_FUNCTION);
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_OPTIONAL(wxDECLARE_SYM_FUNCTION);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
#undef wxDECLARE_SYM_FUNCTION
|
#undef wxDECLARE_SYM_FUNCTION
|
||||||
|
|
||||||
@ -219,10 +312,10 @@ public:
|
|||||||
static void LogError(const wxChar *func);
|
static void LogError(const wxChar *func);
|
||||||
|
|
||||||
// return textual representation of the value of given symbol
|
// return textual representation of the value of given symbol
|
||||||
static wxString DumpSymbol(PSYMBOL_INFO pSymInfo, void *pVariable);
|
static wxString DumpSymbol(wxPSYMBOL_INFO pSymInfo, void *pVariable);
|
||||||
|
|
||||||
// return the name of the symbol with given type index
|
// return the name of the symbol with given type index
|
||||||
static wxString GetSymbolName(PSYMBOL_INFO pSymInfo);
|
static wxString GetSymbolName(wxPSYMBOL_INFO pSymInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// dereference the given symbol, i.e. return symbol which is not a
|
// dereference the given symbol, i.e. return symbol which is not a
|
||||||
@ -232,17 +325,20 @@ private:
|
|||||||
// dereferenced the symbol
|
// dereferenced the symbol
|
||||||
//
|
//
|
||||||
// return the tag of the dereferenced symbol
|
// return the tag of the dereferenced symbol
|
||||||
static SymbolTag DereferenceSymbol(PSYMBOL_INFO pSymInfo, void **ppData);
|
static SymbolTag DereferenceSymbol(wxPSYMBOL_INFO pSymInfo, void **ppData);
|
||||||
|
|
||||||
static wxString DumpField(PSYMBOL_INFO pSymInfo,
|
static wxString DumpField(wxPSYMBOL_INFO pSymInfo,
|
||||||
void *pVariable,
|
void *pVariable,
|
||||||
unsigned level);
|
unsigned level);
|
||||||
|
|
||||||
static wxString DumpBaseType(BasicType bt, DWORD64 length, void *pVariable);
|
static wxString DumpBaseType(BasicType bt, DWORD64 length, void *pVariable);
|
||||||
|
|
||||||
static wxString DumpUDT(PSYMBOL_INFO pSymInfo,
|
static wxString DumpUDT(wxPSYMBOL_INFO pSymInfo,
|
||||||
void *pVariable,
|
void *pVariable,
|
||||||
unsigned level = 0);
|
unsigned level = 0);
|
||||||
|
|
||||||
|
static bool BindDbgHelpFunctions(const wxDynamicLibrary& dllDbgHelp);
|
||||||
|
static bool DoInit();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_DBGHELP
|
#endif // wxUSE_DBGHELP
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Name: wx/msw/stackwalk.h
|
// Name: wx/msw/stackwalk.h
|
||||||
// Purpose: wxStackWalker for MSW
|
// Purpose: wxStackWalker for MSW
|
||||||
// Author: Vadim Zeitlin
|
// Author: Vadim Zeitlin
|
||||||
// Modified by:
|
// Modified by: Suzumizaki-kimitaka 2013-04-09
|
||||||
// Created: 2005-01-08
|
// Created: 2005-01-08
|
||||||
// Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwindows.org>
|
// Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
@ -19,6 +19,7 @@ struct _EXCEPTION_POINTERS;
|
|||||||
|
|
||||||
// and these in dbghelp.h
|
// and these in dbghelp.h
|
||||||
struct _SYMBOL_INFO;
|
struct _SYMBOL_INFO;
|
||||||
|
struct _SYMBOL_INFOW;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxStackFrame
|
// wxStackFrame
|
||||||
@ -52,7 +53,11 @@ public:
|
|||||||
GetParam(size_t n, wxString *type, wxString *name, wxString *value) const;
|
GetParam(size_t n, wxString *type, wxString *name, wxString *value) const;
|
||||||
|
|
||||||
// callback used by OnGetParam(), don't call directly
|
// callback used by OnGetParam(), don't call directly
|
||||||
void OnParam(_SYMBOL_INFO *pSymInfo);
|
#ifdef UNICODE
|
||||||
|
void OnParam(_SYMBOL_INFOW * pSymInfo);
|
||||||
|
#else
|
||||||
|
void OnParam(_SYMBOL_INFO * pSymInfo);
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnGetName();
|
virtual void OnGetName();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Name: src/msw/debughlp.cpp
|
// Name: src/msw/debughlp.cpp
|
||||||
// Purpose: various Win32 debug helpers
|
// Purpose: various Win32 debug helpers
|
||||||
// Author: Vadim Zeitlin
|
// Author: Vadim Zeitlin
|
||||||
// Modified by:
|
// Modified by: Suzumizaki-kimitaka 2013-04-10
|
||||||
// Created: 2005-01-08 (extracted from crashrpt.cpp)
|
// Created: 2005-01-08 (extracted from crashrpt.cpp)
|
||||||
// Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
// Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
@ -62,7 +62,8 @@ wxDO_FOR_ALL_SYM_FUNCS(DEFINE_SYM_FUNCTION);
|
|||||||
|
|
||||||
// load all function we need from the DLL
|
// load all function we need from the DLL
|
||||||
|
|
||||||
static bool BindDbgHelpFunctions(const wxDynamicLibrary& dllDbgHelp)
|
/* static */
|
||||||
|
bool wxDbgHelpDLL::BindDbgHelpFunctions(const wxDynamicLibrary& dllDbgHelp)
|
||||||
{
|
{
|
||||||
#define LOAD_SYM_FUNCTION(func, name) \
|
#define LOAD_SYM_FUNCTION(func, name) \
|
||||||
wxDbgHelpDLL::func = (wxDbgHelpDLL::func ## _t) \
|
wxDbgHelpDLL::func = (wxDbgHelpDLL::func ## _t) \
|
||||||
@ -73,15 +74,27 @@ static bool BindDbgHelpFunctions(const wxDynamicLibrary& dllDbgHelp)
|
|||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDO_FOR_ALL_SYM_FUNCS(LOAD_SYM_FUNCTION);
|
wxDO_FOR_ALL_SYM_FUNCS_REQUIRED(LOAD_SYM_FUNCTION);
|
||||||
|
|
||||||
#undef LOAD_SYM_FUNCTION
|
#undef LOAD_SYM_FUNCTION
|
||||||
|
|
||||||
|
#define LOAD_SYM_FUNCTION_OPTIONAL(func, name) \
|
||||||
|
if ( dllDbgHelp.HasSymbol(wxT(#name)) ) \
|
||||||
|
{ \
|
||||||
|
wxDbgHelpDLL::func = (wxDbgHelpDLL::func ## _t) \
|
||||||
|
dllDbgHelp.GetSymbol(wxT(#name)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDO_FOR_ALL_SYM_FUNCS_OPTIONAL(LOAD_SYM_FUNCTION_OPTIONAL);
|
||||||
|
|
||||||
|
#undef LOAD_SYM_FUNCTION_CAN_FAIL
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by Init() if we hadn't done this before
|
// called by Init() if we hadn't done this before
|
||||||
static bool DoInit()
|
/* static */
|
||||||
|
bool wxDbgHelpDLL::DoInit()
|
||||||
{
|
{
|
||||||
wxDynamicLibrary dllDbgHelp(wxT("dbghelp.dll"), wxDL_VERBATIM);
|
wxDynamicLibrary dllDbgHelp(wxT("dbghelp.dll"), wxDL_VERBATIM);
|
||||||
if ( dllDbgHelp.IsLoaded() )
|
if ( dllDbgHelp.IsLoaded() )
|
||||||
@ -170,13 +183,13 @@ DoGetTypeInfo(DWORD64 base, ULONG ti, IMAGEHLP_SYMBOL_TYPE_INFO type, void *rc)
|
|||||||
|
|
||||||
static inline
|
static inline
|
||||||
bool
|
bool
|
||||||
DoGetTypeInfo(PSYMBOL_INFO pSym, IMAGEHLP_SYMBOL_TYPE_INFO type, void *rc)
|
DoGetTypeInfo(wxPSYMBOL_INFO pSym, IMAGEHLP_SYMBOL_TYPE_INFO type, void *rc)
|
||||||
{
|
{
|
||||||
return DoGetTypeInfo(pSym->ModBase, pSym->TypeIndex, type, rc);
|
return DoGetTypeInfo(pSym->ModBase, pSym->TypeIndex, type, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
wxDbgHelpDLL::BasicType GetBasicType(PSYMBOL_INFO pSym)
|
wxDbgHelpDLL::BasicType GetBasicType(wxPSYMBOL_INFO pSym)
|
||||||
{
|
{
|
||||||
wxDbgHelpDLL::BasicType bt;
|
wxDbgHelpDLL::BasicType bt;
|
||||||
return DoGetTypeInfo(pSym, TI_GET_BASETYPE, &bt)
|
return DoGetTypeInfo(pSym, TI_GET_BASETYPE, &bt)
|
||||||
@ -185,7 +198,7 @@ wxDbgHelpDLL::BasicType GetBasicType(PSYMBOL_INFO pSym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxString wxDbgHelpDLL::GetSymbolName(PSYMBOL_INFO pSym)
|
wxString wxDbgHelpDLL::GetSymbolName(wxPSYMBOL_INFO pSym)
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
|
|
||||||
@ -289,7 +302,7 @@ wxDbgHelpDLL::DumpBaseType(BasicType bt, DWORD64 length, PVOID pAddress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wxString
|
wxString
|
||||||
wxDbgHelpDLL::DumpField(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
wxDbgHelpDLL::DumpField(wxPSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
|
|
||||||
@ -336,7 +349,7 @@ wxDbgHelpDLL::DumpField(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
|||||||
|
|
||||||
|
|
||||||
// now pass to the type representing the type of this member
|
// now pass to the type representing the type of this member
|
||||||
SYMBOL_INFO sym = *pSym;
|
wxSYMBOL_INFO sym = *pSym;
|
||||||
if ( !DoGetTypeInfo(pSym, TI_GET_TYPEID, &sym.TypeIndex) )
|
if ( !DoGetTypeInfo(pSym, TI_GET_TYPEID, &sym.TypeIndex) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -387,7 +400,7 @@ wxDbgHelpDLL::DumpField(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */ wxString
|
/* static */ wxString
|
||||||
wxDbgHelpDLL::DumpUDT(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
wxDbgHelpDLL::DumpUDT(wxPSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
|
|
||||||
@ -454,7 +467,7 @@ wxDbgHelpDLL::DumpUDT(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
|||||||
s << wxT(" {\n");
|
s << wxT(" {\n");
|
||||||
|
|
||||||
// Iterate through all children
|
// Iterate through all children
|
||||||
SYMBOL_INFO sym;
|
wxSYMBOL_INFO sym;
|
||||||
wxZeroMemory(sym);
|
wxZeroMemory(sym);
|
||||||
sym.ModBase = pSym->ModBase;
|
sym.ModBase = pSym->ModBase;
|
||||||
for ( unsigned i = 0; i < dwChildrenCount; i++ )
|
for ( unsigned i = 0; i < dwChildrenCount; i++ )
|
||||||
@ -486,7 +499,7 @@ wxDbgHelpDLL::DumpUDT(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxDbgHelpDLL::SymbolTag
|
wxDbgHelpDLL::SymbolTag
|
||||||
wxDbgHelpDLL::DereferenceSymbol(PSYMBOL_INFO pSym, void **ppData)
|
wxDbgHelpDLL::DereferenceSymbol(wxPSYMBOL_INFO pSym, void **ppData)
|
||||||
{
|
{
|
||||||
SymbolTag tag = SYMBOL_TAG_NULL;
|
SymbolTag tag = SYMBOL_TAG_NULL;
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
@ -523,10 +536,10 @@ wxDbgHelpDLL::DereferenceSymbol(PSYMBOL_INFO pSym, void **ppData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */ wxString
|
/* static */ wxString
|
||||||
wxDbgHelpDLL::DumpSymbol(PSYMBOL_INFO pSym, void *pVariable)
|
wxDbgHelpDLL::DumpSymbol(wxPSYMBOL_INFO pSym, void *pVariable)
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
SYMBOL_INFO symDeref = *pSym;
|
wxSYMBOL_INFO symDeref = *pSym;
|
||||||
switch ( DereferenceSymbol(&symDeref, &pVariable) )
|
switch ( DereferenceSymbol(&symDeref, &pVariable) )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@ -552,6 +565,316 @@ wxDbgHelpDLL::DumpSymbol(PSYMBOL_INFO pSym, void *pVariable)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// do the best functions and structures
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct wxMswEnmLddMdlsHelperStruct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxMswEnmLddMdlsHelperStruct(wxPENUMLOADED_MODULES_CALLBACK64 ptr, PVOID content)
|
||||||
|
: m_pointer_to_callback(ptr), m_user_content(content)
|
||||||
|
{ }
|
||||||
|
wxPENUMLOADED_MODULES_CALLBACK64 m_pointer_to_callback;
|
||||||
|
PVOID m_user_content;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
|
||||||
|
static BOOL CALLBACK wxMswEnmLddMdlsCallback1(
|
||||||
|
PCSTR ModuleName, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext)
|
||||||
|
{
|
||||||
|
wxMswEnmLddMdlsHelperStruct& alternate =
|
||||||
|
*(wxMswEnmLddMdlsHelperStruct*)(UserContext);
|
||||||
|
|
||||||
|
const wxWCharBuffer buf = wxConvLocal.cMB2WC(ModuleName, wxNO_LEN, NULL);
|
||||||
|
return (*alternate.m_pointer_to_callback)
|
||||||
|
(buf.data(), ModuleBase, ModuleSize, alternate.m_user_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CALLBACK wxMswEnmLddMdlsCallback2(
|
||||||
|
PCSTR ModuleName, DWORD_PTR ModuleBase, ULONG ModuleSize, PVOID UserContext)
|
||||||
|
{
|
||||||
|
wxMswEnmLddMdlsHelperStruct& alternate =
|
||||||
|
*(wxMswEnmLddMdlsHelperStruct*)(UserContext);
|
||||||
|
|
||||||
|
const wxWCharBuffer buf = wxConvLocal.cMB2WC(ModuleName, wxNO_LEN, NULL);
|
||||||
|
return (*alternate.m_pointer_to_callback)
|
||||||
|
(buf.data(), ModuleBase, ModuleSize, alternate.m_user_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static BOOL CALLBACK wxMswEnmLddMdlsCallback(
|
||||||
|
PCSTR ModuleName, DWORD_PTR ModuleBase, ULONG ModuleSize, PVOID UserContext)
|
||||||
|
{
|
||||||
|
wxMswEnmLddMdlsHelperStruct& alternate =
|
||||||
|
*(wxMswEnmLddMdlsHelperStruct*)(UserContext);
|
||||||
|
|
||||||
|
return (*alternate.m_pointer_to_callback)
|
||||||
|
(ModuleName, ModuleBase, ModuleSize, alternate.m_user_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // UNICODE
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
BOOL wxDbgHelpDLL::EnumerateLoadedModulesT(
|
||||||
|
HANDLE handle, wxPENUMLOADED_MODULES_CALLBACK64 callback, PVOID pvoid)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
if (EnumerateLoadedModulesW64)
|
||||||
|
{
|
||||||
|
const BOOL retVal = (*EnumerateLoadedModulesW64)(handle, callback, pvoid);
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
if (EnumerateLoadedModules64)
|
||||||
|
{
|
||||||
|
wxMswEnmLddMdlsHelperStruct p(callback, pvoid);
|
||||||
|
const BOOL retVal =
|
||||||
|
(*EnumerateLoadedModules64)
|
||||||
|
(handle, &wxMswEnmLddMdlsCallback1, (PVOID)(&p));
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
if (EnumerateLoadedModules)
|
||||||
|
{
|
||||||
|
wxMswEnmLddMdlsHelperStruct p(callback, pvoid);
|
||||||
|
const BOOL retVal =
|
||||||
|
(*EnumerateLoadedModules)
|
||||||
|
(handle, &wxMswEnmLddMdlsCallback2, (PVOID)(&p));
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
if (EnumerateLoadedModules64)
|
||||||
|
{
|
||||||
|
const BOOL retVal = (*EnumerateLoadedModules64)(handle, callback, pvoid);
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
if (EnumerateLoadedModules)
|
||||||
|
{
|
||||||
|
wxMswEnmLddMdlsHelperStruct p(callback, pvoid);
|
||||||
|
const BOOL retVal =
|
||||||
|
(*EnumerateLoadedModules)
|
||||||
|
(handle, &wxMswEnmLddMdlsCallback, (PVOID)(&p));
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
BOOL wxDbgHelpDLL::SymInitializeT(HANDLE hProcess, LPCTSTR UserSearchPath, BOOL fInvadeProcess)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
if (SymInitializeW)
|
||||||
|
{
|
||||||
|
const BOOL retVal = (*SymInitializeW)(hProcess, UserSearchPath, fInvadeProcess);
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
if (SymInitialize)
|
||||||
|
{
|
||||||
|
BOOL retVal;
|
||||||
|
if (UserSearchPath)
|
||||||
|
{
|
||||||
|
const wxCharBuffer buf = wxConvLocal.cWC2MB(UserSearchPath, wxNO_LEN, NULL);
|
||||||
|
retVal = (*SymInitialize)(hProcess, buf.data(), fInvadeProcess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retVal = (*SymInitialize)(hProcess, NULL, fInvadeProcess);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
if (SymInitialize)
|
||||||
|
{
|
||||||
|
return (*SymInitialize)(hProcess, UserSearchPath, fInvadeProcess);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
BOOL wxDbgHelpDLL::SymFromAddrT(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, wxPSYMBOL_INFO Symbol)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
if (SymFromAddrW)
|
||||||
|
{
|
||||||
|
const BOOL retVal = (*SymFromAddrW)(hProcess, Address, Displacement, Symbol);
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
if (SymFromAddr)
|
||||||
|
{
|
||||||
|
BYTE* symbolBuffer = new BYTE[sizeof(SYMBOL_INFO) + Symbol->MaxNameLen*sizeof(CHAR)];
|
||||||
|
PSYMBOL_INFO data = (SYMBOL_INFO*)(symbolBuffer);
|
||||||
|
wxZeroMemory(*data);
|
||||||
|
data->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
data->MaxNameLen = Symbol->MaxNameLen;
|
||||||
|
if (! (*SymFromAddr)(hProcess, Address, Displacement, data))
|
||||||
|
{
|
||||||
|
delete [] symbolBuffer;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can't refer data->NameLen. It seems to be unmodified.
|
||||||
|
const wxWCharBuffer buf = wxConvLocal.cMB2WC(data->Name, wxNO_LEN, NULL);
|
||||||
|
|
||||||
|
// FIXME: I know too brute but some header names SYMBOL_INFO::Index
|
||||||
|
// and the other one defines it as SYMBOL_INFO::info.
|
||||||
|
const ULONG dstSize = Symbol->SizeOfStruct;
|
||||||
|
CopyMemory(Symbol, data, sizeof(SYMBOL_INFO)-sizeof(CHAR));
|
||||||
|
Symbol->SizeOfStruct = dstSize;
|
||||||
|
Symbol->NameLen = buf.length();
|
||||||
|
wxStrncpy(Symbol->Name, buf.data(), Symbol->MaxNameLen);
|
||||||
|
delete [] symbolBuffer;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
if (SymFromAddr)
|
||||||
|
{
|
||||||
|
return (*SymFromAddr)(hProcess, Address, Displacement, Symbol);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
BOOL wxDbgHelpDLL::SymGetLineFromAddrT(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdrDisplacement, wxPIMAGEHLP_LINE Line)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
if (SymGetLineFromAddrW64)
|
||||||
|
{
|
||||||
|
const BOOL retVal = (*SymGetLineFromAddrW64)(hProcess, dwAddr, pdrDisplacement, Line);
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
// TODO: seems always fail with GetLastError() returns 487 with 32bit binary on 64 bit Windows.
|
||||||
|
}
|
||||||
|
static WCHAR staticBuf[MAX_PATH];
|
||||||
|
if (SymGetLineFromAddr64)
|
||||||
|
{
|
||||||
|
IMAGEHLP_LINE64 LineAlternate;
|
||||||
|
LineAlternate.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||||
|
if ((*SymGetLineFromAddr64)(hProcess, dwAddr, pdrDisplacement, &LineAlternate))
|
||||||
|
{
|
||||||
|
const wxWCharBuffer ConvBuf =
|
||||||
|
wxConvLocal.cMB2WC(LineAlternate.FileName, wxNO_LEN, NULL);
|
||||||
|
wxStrncpy(staticBuf, ConvBuf.data(), MAX_PATH);
|
||||||
|
Line->Key = LineAlternate.Key;
|
||||||
|
Line->LineNumber = LineAlternate.LineNumber;
|
||||||
|
Line->FileName = staticBuf;
|
||||||
|
Line->Address = LineAlternate.Address;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SymGetLineFromAddr)
|
||||||
|
{
|
||||||
|
IMAGEHLP_LINE LineAlternate;
|
||||||
|
LineAlternate.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||||
|
if ((*SymGetLineFromAddr)(hProcess, dwAddr, pdrDisplacement, &LineAlternate))
|
||||||
|
{
|
||||||
|
const wxWCharBuffer ConvBuf =
|
||||||
|
wxConvLocal.cMB2WC(LineAlternate.FileName, wxNO_LEN, NULL);
|
||||||
|
wxStrncpy(staticBuf, ConvBuf.data(), MAX_PATH);
|
||||||
|
Line->Key = LineAlternate.Key;
|
||||||
|
Line->LineNumber = LineAlternate.LineNumber;
|
||||||
|
Line->FileName = staticBuf;
|
||||||
|
Line->Address = LineAlternate.Address;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
if (SymGetLineFromAddr64)
|
||||||
|
{
|
||||||
|
return (*SymGetLineFromAddr64)(hProcess, dwAddr, pdrDisplacement, Line);
|
||||||
|
}
|
||||||
|
if (SymGetLineFromAddr)
|
||||||
|
{
|
||||||
|
IMAGEHLP_LINE LineAlternate;
|
||||||
|
LineAlternate.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||||
|
if ((*SymGetLineFromAddr)(hProcess, dwAddr, pdrDisplacement, &LineAlternate))
|
||||||
|
{
|
||||||
|
Line->Key = LineAlternate.Key;
|
||||||
|
Line->LineNumber = LineAlternate.LineNumber;
|
||||||
|
Line->FileName = LineAlternate.FileName;
|
||||||
|
Line->Address = LineAlternate.Address;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wxMswSymEnumSymbolsHelperStruct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxMswSymEnumSymbolsHelperStruct(PSYM_ENUMERATESYMBOLS_CALLBACKW ptr, PVOID content)
|
||||||
|
: m_pointer_to_callback(ptr), m_user_content(content)
|
||||||
|
{ }
|
||||||
|
PSYM_ENUMERATESYMBOLS_CALLBACKW m_pointer_to_callback;
|
||||||
|
PVOID m_user_content;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
|
||||||
|
static BOOL CALLBACK wxMswSymEnumSymbolsHelperCallback(
|
||||||
|
PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
|
||||||
|
{
|
||||||
|
wxMswSymEnumSymbolsHelperStruct& alternate =
|
||||||
|
*(wxMswSymEnumSymbolsHelperStruct*)(UserContext);
|
||||||
|
const wxWCharBuffer buf = wxConvLocal.cMB2WC(pSymInfo->Name, pSymInfo->MaxNameLen, NULL);
|
||||||
|
BYTE* symbolBuffer = new BYTE[sizeof(SYMBOL_INFOW) + buf.length()*sizeof(WCHAR)];
|
||||||
|
SYMBOL_INFOW* data = (SYMBOL_INFOW*)(symbolBuffer);
|
||||||
|
|
||||||
|
// FIXME: I know too brute but some header names SYMBOL_INFO::Index
|
||||||
|
// and the other one defines it as SYMBOL_INFO::info.
|
||||||
|
CopyMemory(data, pSymInfo, sizeof(SYMBOL_INFO)-sizeof(CHAR));
|
||||||
|
data->SizeOfStruct = sizeof(SYMBOL_INFOW);
|
||||||
|
wxStrncpy(data->Name, buf.data(), buf.length());
|
||||||
|
BOOL retVal = (*alternate.m_pointer_to_callback)(data, SymbolSize, alternate.m_user_content);
|
||||||
|
delete [] symbolBuffer;
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // UNICODE
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
BOOL wxDbgHelpDLL::SymEnumSymbolsT(HANDLE hProcess, ULONG64 baseOfDll, PCTSTR Mask,
|
||||||
|
wxPSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, const PVOID UserContext)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
if (SymEnumSymbolsW)
|
||||||
|
{
|
||||||
|
const BOOL retVal = (*SymEnumSymbolsW)(hProcess, baseOfDll, Mask, EnumSymbolsCallback, UserContext);
|
||||||
|
if (retVal)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
if (SymEnumSymbols)
|
||||||
|
{
|
||||||
|
wxMswSymEnumSymbolsHelperStruct p(EnumSymbolsCallback, UserContext);
|
||||||
|
const wxCharBuffer buf = wxConvLocal.cWC2MB(Mask ? Mask : L"", wxNO_LEN, NULL);
|
||||||
|
return (*SymEnumSymbols)(hProcess, baseOfDll, buf.data(),
|
||||||
|
wxMswSymEnumSymbolsHelperCallback, (PVOID)(&p));
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
if (SymEnumSymbols)
|
||||||
|
{
|
||||||
|
return (*SymEnumSymbols)(hProcess, baseOfDll, Mask, EnumSymbolsCallback, UserContext);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// debugging helpers
|
// debugging helpers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Name: src/msw/dlmsw.cpp
|
// Name: src/msw/dlmsw.cpp
|
||||||
// Purpose: Win32-specific part of wxDynamicLibrary and related classes
|
// Purpose: Win32-specific part of wxDynamicLibrary and related classes
|
||||||
// Author: Vadim Zeitlin
|
// Author: Vadim Zeitlin
|
||||||
// Modified by:
|
// Modified by: Suzumizaki-kimitaka 2013-04-09
|
||||||
// Created: 2005-01-10 (partly extracted from common/dynlib.cpp)
|
// Created: 2005-01-10 (partly extracted from common/dynlib.cpp)
|
||||||
// Copyright: (c) 1998-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
// Copyright: (c) 1998-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
@ -28,6 +28,11 @@
|
|||||||
#include "wx/msw/debughlp.h"
|
#include "wx/msw/debughlp.h"
|
||||||
#include "wx/filename.h"
|
#include "wx/filename.h"
|
||||||
|
|
||||||
|
// defined for TDM's GCC/mingw32
|
||||||
|
#ifndef PCTSTR
|
||||||
|
#define PCTSTR LPCTSTR
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private classes
|
// private classes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -77,15 +82,8 @@ public:
|
|||||||
wxVersionDLL *verDLL;
|
wxVersionDLL *verDLL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: fix EnumerateLoadedModules() to use EnumerateLoadedModules64()
|
|
||||||
#ifdef __WIN64__
|
|
||||||
typedef DWORD64 DWORD_32_64;
|
|
||||||
#else
|
|
||||||
typedef DWORD DWORD_32_64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static BOOL CALLBACK
|
static BOOL CALLBACK
|
||||||
EnumModulesProc(PCSTR name, DWORD_32_64 base, ULONG size, void *data);
|
EnumModulesProc(PCTSTR name, DWORD64 base, ULONG size, PVOID data);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -113,7 +111,7 @@ wxVersionDLL::wxVersionDLL()
|
|||||||
#endif // UNICODE/ANSI
|
#endif // UNICODE/ANSI
|
||||||
|
|
||||||
#define LOAD_VER_FUNCTION(name) \
|
#define LOAD_VER_FUNCTION(name) \
|
||||||
m_pfn ## name = (name ## _t)m_dll.GetSymbol(wxT(#name SUFFIX)); \
|
m_pfn ## name = (name ## _t)m_dll.GetSymbol(wxT(#name SUFFIX)); \
|
||||||
if ( !m_pfn ## name ) \
|
if ( !m_pfn ## name ) \
|
||||||
{ \
|
{ \
|
||||||
m_dll.Unload(); \
|
m_dll.Unload(); \
|
||||||
@ -172,17 +170,21 @@ wxString wxVersionDLL::GetFileVersion(const wxString& filename) const
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
BOOL CALLBACK
|
BOOL CALLBACK
|
||||||
wxDynamicLibraryDetailsCreator::EnumModulesProc(PCSTR name,
|
wxDynamicLibraryDetailsCreator::EnumModulesProc(PCTSTR name,
|
||||||
DWORD_32_64 base,
|
DWORD64 base,
|
||||||
ULONG size,
|
ULONG size,
|
||||||
void *data)
|
PVOID data)
|
||||||
{
|
{
|
||||||
EnumModulesProcParams *params = (EnumModulesProcParams *)data;
|
EnumModulesProcParams *params = (EnumModulesProcParams *)data;
|
||||||
|
|
||||||
wxDynamicLibraryDetails *details = new wxDynamicLibraryDetails;
|
wxDynamicLibraryDetails *details = new wxDynamicLibraryDetails;
|
||||||
|
|
||||||
// fill in simple properties
|
// fill in simple properties
|
||||||
|
#ifdef UNICODE
|
||||||
details->m_name = name;
|
details->m_name = name;
|
||||||
|
#else
|
||||||
|
details->m_name = wxString(name, wxConvLocal);
|
||||||
|
#endif
|
||||||
details->m_address = wxUIntToPtr(base);
|
details->m_address = wxUIntToPtr(base);
|
||||||
details->m_length = size;
|
details->m_length = size;
|
||||||
|
|
||||||
@ -320,20 +322,14 @@ wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
|
|||||||
params.dlls = &dlls;
|
params.dlls = &dlls;
|
||||||
params.verDLL = &verDLL;
|
params.verDLL = &verDLL;
|
||||||
|
|
||||||
// Note that the cast of EnumModulesProc is needed because the type of
|
if ( !wxDbgHelpDLL::EnumerateLoadedModulesT
|
||||||
// PENUMLOADED_MODULES_CALLBACK changed: in old SDK versions its first
|
|
||||||
// argument was non-const PSTR while now it's PCSTR. By explicitly
|
|
||||||
// casting to whatever the currently used headers require we ensure
|
|
||||||
// that the code compilers in any case.
|
|
||||||
if ( !wxDbgHelpDLL::EnumerateLoadedModules
|
|
||||||
(
|
(
|
||||||
::GetCurrentProcess(),
|
::GetCurrentProcess(),
|
||||||
(PENUMLOADED_MODULES_CALLBACK)
|
|
||||||
wxDynamicLibraryDetailsCreator::EnumModulesProc,
|
wxDynamicLibraryDetailsCreator::EnumModulesProc,
|
||||||
¶ms
|
¶ms
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("EnumerateLoadedModules"));
|
wxLogLastError(wxT("EnumerateLoadedModulesT"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // wxUSE_DBGHELP
|
#endif // wxUSE_DBGHELP
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
// Name: src/msw/stackwalk.cpp
|
// Name: src/msw/stackwalk.cpp
|
||||||
// Purpose: wxStackWalker implementation for Win32
|
// Purpose: wxStackWalker implementation for Win32
|
||||||
// Author: Vadim Zeitlin
|
// Author: Vadim Zeitlin
|
||||||
// Modified by: Artur Bac 2010-10-01 AMD64 Port
|
// Modified by: Artur Bac 2010-10-01 AMD64 Port,
|
||||||
|
// Suzumizaki-kimitaka 2013-04-09
|
||||||
// Created: 2005-01-08
|
// Created: 2005-01-08
|
||||||
// Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
// Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
@ -51,15 +52,15 @@ void wxStackFrame::OnGetName()
|
|||||||
|
|
||||||
// get the name of the function for this stack frame entry
|
// get the name of the function for this stack frame entry
|
||||||
static const size_t MAX_NAME_LEN = 1024;
|
static const size_t MAX_NAME_LEN = 1024;
|
||||||
BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_NAME_LEN];
|
BYTE symbolBuffer[sizeof(wxSYMBOL_INFO) + MAX_NAME_LEN*sizeof(TCHAR)];
|
||||||
wxZeroMemory(symbolBuffer);
|
wxZeroMemory(symbolBuffer);
|
||||||
|
|
||||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
|
wxPSYMBOL_INFO pSymbol = (wxPSYMBOL_INFO)symbolBuffer;
|
||||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
pSymbol->SizeOfStruct = sizeof(wxSYMBOL_INFO);
|
||||||
pSymbol->MaxNameLen = MAX_NAME_LEN;
|
pSymbol->MaxNameLen = MAX_NAME_LEN;
|
||||||
|
|
||||||
DWORD64 symDisplacement = 0;
|
DWORD64 symDisplacement = 0;
|
||||||
if ( !wxDbgHelpDLL::SymFromAddr
|
if ( !wxDbgHelpDLL::SymFromAddrT
|
||||||
(
|
(
|
||||||
::GetCurrentProcess(),
|
::GetCurrentProcess(),
|
||||||
GetSymAddr(),
|
GetSymAddr(),
|
||||||
@ -67,11 +68,14 @@ void wxStackFrame::OnGetName()
|
|||||||
pSymbol
|
pSymbol
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
wxDbgHelpDLL::LogError(wxT("SymFromAddr"));
|
wxDbgHelpDLL::LogError(wxT("SymFromAddrT"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef UNICODE
|
||||||
m_name = wxString::FromAscii(pSymbol->Name);
|
m_name = pSymbol->Name;
|
||||||
|
#else
|
||||||
|
m_name = wxString(pSymbol->Name, wxConvLocal);
|
||||||
|
#endif
|
||||||
m_offset = symDisplacement;
|
m_offset = symDisplacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,9 +87,9 @@ void wxStackFrame::OnGetLocation()
|
|||||||
m_hasLocation = true;
|
m_hasLocation = true;
|
||||||
|
|
||||||
// get the source line for this stack frame entry
|
// get the source line for this stack frame entry
|
||||||
IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
|
wxIMAGEHLP_LINE lineInfo = { sizeof(wxIMAGEHLP_LINE) };
|
||||||
DWORD dwLineDisplacement;
|
DWORD dwLineDisplacement;
|
||||||
if ( !wxDbgHelpDLL::SymGetLineFromAddr
|
if ( !wxDbgHelpDLL::SymGetLineFromAddrT
|
||||||
(
|
(
|
||||||
::GetCurrentProcess(),
|
::GetCurrentProcess(),
|
||||||
GetSymAddr(),
|
GetSymAddr(),
|
||||||
@ -95,11 +99,14 @@ void wxStackFrame::OnGetLocation()
|
|||||||
{
|
{
|
||||||
// it is normal that we don't have source info for some symbols,
|
// it is normal that we don't have source info for some symbols,
|
||||||
// notably all the ones from the system DLLs...
|
// notably all the ones from the system DLLs...
|
||||||
//wxDbgHelpDLL::LogError(wxT("SymGetLineFromAddr"));
|
//wxDbgHelpDLL::LogError(wxT("SymGetLineFromAddr64"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef UNICODE
|
||||||
m_filename = wxString::FromAscii(lineInfo.FileName);
|
m_filename = lineInfo.FileName;
|
||||||
|
#else
|
||||||
|
m_filename = wxString(lineInfo.FileName, wxConvLocal);
|
||||||
|
#endif
|
||||||
m_line = lineInfo.LineNumber;
|
m_line = lineInfo.LineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,11 +132,15 @@ wxStackFrame::GetParam(size_t n,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxStackFrame::OnParam(PSYMBOL_INFO pSymInfo)
|
void wxStackFrame::OnParam(wxPSYMBOL_INFO pSymInfo)
|
||||||
{
|
{
|
||||||
m_paramTypes.Add(wxEmptyString);
|
m_paramTypes.Add(wxEmptyString);
|
||||||
|
|
||||||
m_paramNames.Add(wxString::FromAscii(pSymInfo->Name));
|
#ifdef UNICODE
|
||||||
|
m_paramNames.Add(pSymInfo->Name);
|
||||||
|
#else
|
||||||
|
m_paramNames.Add(wxString(pSymInfo->Name, wxConvLocal));
|
||||||
|
#endif
|
||||||
|
|
||||||
// if symbol information is corrupted and we crash, the exception is going
|
// if symbol information is corrupted and we crash, the exception is going
|
||||||
// to be ignored when we're called from WalkFromException() because of the
|
// to be ignored when we're called from WalkFromException() because of the
|
||||||
@ -158,7 +169,7 @@ void wxStackFrame::OnParam(PSYMBOL_INFO pSymInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL CALLBACK
|
BOOL CALLBACK
|
||||||
EnumSymbolsProc(PSYMBOL_INFO pSymInfo, ULONG WXUNUSED(SymSize), PVOID data)
|
EnumSymbolsProc(wxPSYMBOL_INFO pSymInfo, ULONG WXUNUSED(SymSize), PVOID data)
|
||||||
{
|
{
|
||||||
wxStackFrame *frame = static_cast<wxStackFrame *>(data);
|
wxStackFrame *frame = static_cast<wxStackFrame *>(data);
|
||||||
|
|
||||||
@ -195,7 +206,7 @@ void wxStackFrame::OnGetParam()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !wxDbgHelpDLL::SymEnumSymbols
|
if ( !wxDbgHelpDLL::SymEnumSymbolsT
|
||||||
(
|
(
|
||||||
::GetCurrentProcess(),
|
::GetCurrentProcess(),
|
||||||
NULL, // DLL base: use current context
|
NULL, // DLL base: use current context
|
||||||
@ -204,7 +215,7 @@ void wxStackFrame::OnGetParam()
|
|||||||
this // data to pass to it
|
this // data to pass to it
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
wxDbgHelpDLL::LogError(wxT("SymEnumSymbols"));
|
wxDbgHelpDLL::LogError(wxT("SymEnumSymbolsT"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,14 +243,14 @@ void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip, size_t maxDepth)
|
|||||||
// below which should be a real handle... so this is what we use
|
// below which should be a real handle... so this is what we use
|
||||||
const HANDLE hProcess = ::GetCurrentProcess();
|
const HANDLE hProcess = ::GetCurrentProcess();
|
||||||
|
|
||||||
if ( !wxDbgHelpDLL::SymInitialize
|
if ( !wxDbgHelpDLL::SymInitializeT
|
||||||
(
|
(
|
||||||
hProcess,
|
hProcess,
|
||||||
NULL, // use default symbol search path
|
NULL, // use default symbol search path
|
||||||
TRUE // load symbols for all loaded modules
|
TRUE // load symbols for all loaded modules
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
wxDbgHelpDLL::LogError(wxT("SymInitialize"));
|
wxDbgHelpDLL::LogError(wxT("SymInitializeT"));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -382,7 +393,7 @@ wxStackFrame::GetParam(size_t WXUNUSED(n),
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxStackFrame::OnParam(_SYMBOL_INFO * WXUNUSED(pSymInfo))
|
void wxStackFrame::OnParam(wxPSYMBOL_INFO WXUNUSED(pSymInfo))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user