1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/msw/debughlp.h
3 // Purpose: wraps dbghelp.h standard file
4 // Author: Vadim Zeitlin
6 // Created: 2005-01-08 (extracted from msw/crashrpt.cpp)
7 // Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_MSW_DEBUGHLPH_H_
12 #define _WX_MSW_DEBUGHLPH_H_
14 #include "wx/dynlib.h"
16 #include "wx/msw/wrapwin.h"
20 #include "wx/msw/private.h"
22 // All known versions of imagehlp.h define API_VERSION_NUMBER but it's not
23 // documented, so deal with the possibility that it's not defined just in case.
24 #ifndef API_VERSION_NUMBER
25 #define API_VERSION_NUMBER 0
28 // wxUSE_DBGHELP is a bit special as it is not defined in wx/setup.h and we try
29 // to auto-detect whether we should be using debug help API or not ourselves
30 // below. However if the auto-detection fails, you can always predefine it as 0
31 // to avoid even trying.
33 // The version of imagehlp.h from VC6 (7) is too old and is missing some
34 // required symbols while the version from VC7 (9) is good enough. As we
35 // don't know anything about version 8, don't use it unless we can test it.
36 #if API_VERSION_NUMBER >= 9
37 #define wxUSE_DBGHELP 1
39 #define wxUSE_DBGHELP 0
45 // ----------------------------------------------------------------------------
46 // wxDbgHelpDLL: dynamically load dbghelp.dll functions
47 // ----------------------------------------------------------------------------
49 // wrapper for some functions from dbghelp.dll
51 // MT note: this class is not MT safe and should be only used from a single
52 // thread at a time (this is so because dbghelp.dll is not MT-safe
57 // some useful constants not present in debughlp.h (stolen from DIA SDK)
71 BASICTYPE_CURRENCY
= 25,
73 BASICTYPE_VARIANT
= 27,
74 BASICTYPE_COMPLEX
= 28,
77 BASICTYPE_HRESULT
= 31,
86 SYMBOL_TAG_COMPILAND_DETAILS
,
87 SYMBOL_TAG_COMPILAND_ENV
,
91 SYMBOL_TAG_ANNOTATION
,
93 SYMBOL_TAG_PUBLIC_SYMBOL
,
96 SYMBOL_TAG_FUNCTION_TYPE
,
97 SYMBOL_TAG_POINTER_TYPE
,
98 SYMBOL_TAG_ARRAY_TYPE
,
101 SYMBOL_TAG_BASE_CLASS
,
103 SYMBOL_TAG_FUNCTION_ARG_TYPE
,
104 SYMBOL_TAG_FUNC_DEBUG_START
,
105 SYMBOL_TAG_FUNC_DEBUG_END
,
106 SYMBOL_TAG_USING_NAMESPACE
,
107 SYMBOL_TAG_VTABLE_SHAPE
,
111 SYMBOL_TAG_CUSTOM_TYPE
,
112 SYMBOL_TAG_MANAGED_TYPE
,
113 SYMBOL_TAG_DIMENSION
,
123 DATA_OBJECT_PTR
, // "this" pointer
142 typedef DWORD (WINAPI
*SymGetOptions_t
)();
143 typedef DWORD (WINAPI
*SymSetOptions_t
)(DWORD
);
144 typedef BOOL (WINAPI
*SymInitialize_t
)(HANDLE
, LPSTR
, BOOL
);
145 typedef BOOL (WINAPI
*StackWalk_t
)(DWORD
, HANDLE
, HANDLE
, LPSTACKFRAME
,
146 LPVOID
, PREAD_PROCESS_MEMORY_ROUTINE
,
147 PFUNCTION_TABLE_ACCESS_ROUTINE
,
148 PGET_MODULE_BASE_ROUTINE
,
149 PTRANSLATE_ADDRESS_ROUTINE
);
150 typedef BOOL (WINAPI
*SymFromAddr_t
)(HANDLE
, DWORD64
, PDWORD64
, PSYMBOL_INFO
);
151 typedef LPVOID (WINAPI
*SymFunctionTableAccess_t
)(HANDLE
, DWORD_PTR
);
152 typedef DWORD_PTR (WINAPI
*SymGetModuleBase_t
)(HANDLE
, DWORD_PTR
);
153 typedef BOOL (WINAPI
*SymGetLineFromAddr_t
)(HANDLE
, DWORD_PTR
,
154 PDWORD
, PIMAGEHLP_LINE
);
155 typedef BOOL (WINAPI
*SymSetContext_t
)(HANDLE
, PIMAGEHLP_STACK_FRAME
,
157 typedef BOOL (WINAPI
*SymEnumSymbols_t
)(HANDLE
, ULONG64
, PCSTR
,
158 PSYM_ENUMERATESYMBOLS_CALLBACK
, PVOID
);
159 typedef BOOL (WINAPI
*SymGetTypeInfo_t
)(HANDLE
, DWORD64
, ULONG
,
160 IMAGEHLP_SYMBOL_TYPE_INFO
, PVOID
);
161 typedef BOOL (WINAPI
*SymCleanup_t
)(HANDLE
);
162 typedef BOOL (WINAPI
*EnumerateLoadedModules_t
)(HANDLE
, PENUMLOADED_MODULES_CALLBACK
, PVOID
);
163 typedef BOOL (WINAPI
*MiniDumpWriteDump_t
)(HANDLE
, DWORD
, HANDLE
,
165 CONST PMINIDUMP_EXCEPTION_INFORMATION
,
166 CONST PMINIDUMP_USER_STREAM_INFORMATION
,
167 CONST PMINIDUMP_CALLBACK_INFORMATION
);
169 // The macro called by wxDO_FOR_ALL_SYM_FUNCS() below takes 2 arguments:
170 // the name of the function in the program code, which never has "64"
171 // suffix, and the name of the function in the DLL which can have "64"
172 // suffix in some cases. These 2 helper macros call the macro with the
173 // correct arguments in both cases.
174 #define wxSYM_CALL(what, name) what(name, name)
175 #if defined(_M_AMD64)
176 #define wxSYM_CALL_64(what, name) what(name, name ## 64)
178 // Also undo all the "helpful" definitions done by imagehlp.h that map 32
179 // bit functions to 64 bit ones, we don't need this as we do it ourselves.
181 #undef SymFunctionTableAccess
182 #undef SymGetModuleBase
183 #undef SymGetLineFromAddr
184 #undef EnumerateLoadedModules
186 #define wxSYM_CALL_64(what, name) what(name, name)
189 #define wxDO_FOR_ALL_SYM_FUNCS(what) \
190 wxSYM_CALL_64(what, StackWalk); \
191 wxSYM_CALL_64(what, SymFunctionTableAccess); \
192 wxSYM_CALL_64(what, SymGetModuleBase); \
193 wxSYM_CALL_64(what, SymGetLineFromAddr); \
194 wxSYM_CALL_64(what, EnumerateLoadedModules); \
196 wxSYM_CALL(what, SymGetOptions); \
197 wxSYM_CALL(what, SymSetOptions); \
198 wxSYM_CALL(what, SymInitialize); \
199 wxSYM_CALL(what, SymFromAddr); \
200 wxSYM_CALL(what, SymSetContext); \
201 wxSYM_CALL(what, SymEnumSymbols); \
202 wxSYM_CALL(what, SymGetTypeInfo); \
203 wxSYM_CALL(what, SymCleanup); \
204 wxSYM_CALL(what, MiniDumpWriteDump)
206 #define wxDECLARE_SYM_FUNCTION(func, name) static func ## _t func
208 wxDO_FOR_ALL_SYM_FUNCS(wxDECLARE_SYM_FUNCTION
);
210 #undef wxDECLARE_SYM_FUNCTION
212 // load all functions from DLL, return true if ok
215 // return the string with the error message explaining why Init() failed
216 static const wxString
& GetErrorMessage();
218 // log error returned by the given function to debug output
219 static void LogError(const wxChar
*func
);
221 // return textual representation of the value of given symbol
222 static wxString
DumpSymbol(PSYMBOL_INFO pSymInfo
, void *pVariable
);
224 // return the name of the symbol with given type index
225 static wxString
GetSymbolName(PSYMBOL_INFO pSymInfo
);
228 // dereference the given symbol, i.e. return symbol which is not a
229 // pointer/reference any more
231 // if ppData != NULL, dereference the pointer as many times as we
232 // dereferenced the symbol
234 // return the tag of the dereferenced symbol
235 static SymbolTag
DereferenceSymbol(PSYMBOL_INFO pSymInfo
, void **ppData
);
237 static wxString
DumpField(PSYMBOL_INFO pSymInfo
,
241 static wxString
DumpBaseType(BasicType bt
, DWORD64 length
, void *pVariable
);
243 static wxString
DumpUDT(PSYMBOL_INFO pSymInfo
,
248 #endif // wxUSE_DBGHELP
250 #endif // _WX_MSW_DEBUGHLPH_H_