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:
		| @@ -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)) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user