]> git.saurik.com Git - wxWidgets.git/blob - include/wx/msw/debughlp.h
created a reusable interface to dbghelp API
[wxWidgets.git] / include / wx / msw / debughlp.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/msw/wrapdbgh.h
3 // Purpose: wraps dbghelp.h standard file
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 2005-01-08 (extracted from msw/crashrpt.cpp)
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003-2005 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_MSW_DEBUGHLPH_H_
13 #define _WX_MSW_DEBUGHLPH_H_
14
15 #include "wx/dynlib.h"
16
17 #include "wx/msw/wrapwin.h"
18 #include <imagehlp.h>
19 #include "wx/msw/private.h"
20
21 // we need to determine whether we have the declarations for the function in
22 // debughlp.dll version 5.81 (at least) and we check for DBHLPAPI to test this
23 //
24 // reasons:
25 // - VC6 version of imagehlp.h doesn't define it
26 // - VC7 one does
27 // - testing for compiler version doesn't work as you can install and use
28 // the new SDK headers with VC6
29 //
30 // in any case, the user may override by defining wxUSE_DBGHELP himself
31 #ifndef wxUSE_DBGHELP
32 #ifdef DBHLPAPI
33 #define wxUSE_DBGHELP 1
34 #else
35 #define wxUSE_DBGHELP 0
36 #endif
37 #endif
38
39 #if wxUSE_DBGHELP
40
41 // ----------------------------------------------------------------------------
42 // wxDbgHelpDLL: dynamically load dbghelp.dll functions
43 // ----------------------------------------------------------------------------
44
45 // wrapper for some functions from dbghelp.dll
46 //
47 // MT note: this class is not MT safe and should be only used from a single
48 // thread at a time (this is so because dbghelp.dll is not MT-safe
49 // itself anyhow)
50 class wxDbgHelpDLL
51 {
52 public:
53 // some useful constants not present in debughlp.h (stolen from DIA SDK)
54 enum BasicType
55 {
56 BASICTYPE_NOTYPE = 0,
57 BASICTYPE_VOID = 1,
58 BASICTYPE_CHAR = 2,
59 BASICTYPE_WCHAR = 3,
60 BASICTYPE_INT = 6,
61 BASICTYPE_UINT = 7,
62 BASICTYPE_FLOAT = 8,
63 BASICTYPE_BCD = 9,
64 BASICTYPE_BOOL = 10,
65 BASICTYPE_LONG = 13,
66 BASICTYPE_ULONG = 14,
67 BASICTYPE_CURRENCY = 25,
68 BASICTYPE_DATE = 26,
69 BASICTYPE_VARIANT = 27,
70 BASICTYPE_COMPLEX = 28,
71 BASICTYPE_BIT = 29,
72 BASICTYPE_BSTR = 30,
73 BASICTYPE_HRESULT = 31,
74 BASICTYPE_MAX
75 };
76
77 enum SymbolTag
78 {
79 SYMBOL_TAG_NULL,
80 SYMBOL_TAG_EXE,
81 SYMBOL_TAG_COMPILAND,
82 SYMBOL_TAG_COMPILAND_DETAILS,
83 SYMBOL_TAG_COMPILAND_ENV,
84 SYMBOL_TAG_FUNCTION,
85 SYMBOL_TAG_BLOCK,
86 SYMBOL_TAG_DATA,
87 SYMBOL_TAG_ANNOTATION,
88 SYMBOL_TAG_LABEL,
89 SYMBOL_TAG_PUBLIC_SYMBOL,
90 SYMBOL_TAG_UDT,
91 SYMBOL_TAG_ENUM,
92 SYMBOL_TAG_FUNCTION_TYPE,
93 SYMBOL_TAG_POINTER_TYPE,
94 SYMBOL_TAG_ARRAY_TYPE,
95 SYMBOL_TAG_BASE_TYPE,
96 SYMBOL_TAG_TYPEDEF,
97 SYMBOL_TAG_BASE_CLASS,
98 SYMBOL_TAG_FRIEND,
99 SYMBOL_TAG_FUNCTION_ARG_TYPE,
100 SYMBOL_TAG_FUNC_DEBUG_START,
101 SYMBOL_TAG_FUNC_DEBUG_END,
102 SYMBOL_TAG_USING_NAMESPACE,
103 SYMBOL_TAG_VTABLE_SHAPE,
104 SYMBOL_TAG_VTABLE,
105 SYMBOL_TAG_CUSTOM,
106 SYMBOL_TAG_THUNK,
107 SYMBOL_TAG_CUSTOM_TYPE,
108 SYMBOL_TAG_MANAGED_TYPE,
109 SYMBOL_TAG_DIMENSION,
110 SYMBOL_TAG_MAX
111 };
112
113 enum DataKind
114 {
115 DATA_UNKNOWN,
116 DATA_LOCAL,
117 DATA_STATIC_LOCAL,
118 DATA_PARAM,
119 DATA_OBJECT_PTR, // "this" pointer
120 DATA_FILE_STATIC,
121 DATA_GLOBAL,
122 DATA_MEMBER,
123 DATA_STATIC_MEMBER,
124 DATA_CONSTANT,
125 DATA_MAX
126 };
127
128 enum UdtKind
129 {
130 UDT_STRUCT,
131 UDT_CLASS,
132 UDT_UNION,
133 UDT_MAX
134 };
135
136
137 // function types
138 typedef DWORD (WINAPI *SymGetOptions_t)();
139 typedef DWORD (WINAPI *SymSetOptions_t)(DWORD);
140 typedef BOOL (WINAPI *SymInitialize_t)(HANDLE, LPSTR, BOOL);
141 typedef BOOL (WINAPI *StackWalk_t)(DWORD, HANDLE, HANDLE, LPSTACKFRAME,
142 LPVOID, PREAD_PROCESS_MEMORY_ROUTINE,
143 PFUNCTION_TABLE_ACCESS_ROUTINE,
144 PGET_MODULE_BASE_ROUTINE,
145 PTRANSLATE_ADDRESS_ROUTINE);
146 typedef BOOL (WINAPI *SymFromAddr_t)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
147 typedef LPVOID (WINAPI *SymFunctionTableAccess_t)(HANDLE, DWORD);
148 typedef DWORD (WINAPI *SymGetModuleBase_t)(HANDLE, DWORD);
149 typedef BOOL (WINAPI *SymGetLineFromAddr_t)(HANDLE, DWORD,
150 PDWORD, PIMAGEHLP_LINE);
151 typedef BOOL (WINAPI *SymSetContext_t)(HANDLE, PIMAGEHLP_STACK_FRAME,
152 PIMAGEHLP_CONTEXT);
153 typedef BOOL (WINAPI *SymEnumSymbols_t)(HANDLE, ULONG64, PCSTR,
154 PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID);
155 typedef BOOL (WINAPI *SymGetTypeInfo_t)(HANDLE, DWORD64, ULONG,
156 IMAGEHLP_SYMBOL_TYPE_INFO, PVOID);
157 typedef BOOL (WINAPI *SymCleanup_t)(HANDLE);
158 typedef BOOL (WINAPI *EnumerateLoadedModules_t)(HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID);
159 typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
160 MINIDUMP_TYPE,
161 CONST PMINIDUMP_EXCEPTION_INFORMATION,
162 CONST PMINIDUMP_USER_STREAM_INFORMATION,
163 CONST PMINIDUMP_CALLBACK_INFORMATION);
164
165 #define wxDO_FOR_ALL_SYM_FUNCS(what) \
166 what(SymGetOptions); \
167 what(SymSetOptions); \
168 what(SymInitialize); \
169 what(StackWalk); \
170 what(SymFromAddr); \
171 what(SymFunctionTableAccess); \
172 what(SymGetModuleBase); \
173 what(SymGetLineFromAddr); \
174 what(SymSetContext); \
175 what(SymEnumSymbols); \
176 what(SymGetTypeInfo); \
177 what(SymCleanup); \
178 what(EnumerateLoadedModules); \
179 what(MiniDumpWriteDump)
180
181 #define wxDECLARE_SYM_FUNCTION(func) static func ## _t func
182
183 wxDO_FOR_ALL_SYM_FUNCS(wxDECLARE_SYM_FUNCTION);
184
185 #undef wxDECLARE_SYM_FUNCTION
186
187 // load all functions from DLL, return true if ok
188 static bool Init();
189
190 // return the string with the error message explaining why Init() failed
191 static const wxString& GetErrorMessage();
192
193 // log error returned by the given function to debug output
194 static void LogError(const wxChar *func);
195
196 // return textual representation of the value of given symbol
197 static wxString DumpSymbol(PSYMBOL_INFO pSymInfo, void *pVariable);
198
199 // return the name of the symbol with given type index
200 static wxString GetSymbolName(PSYMBOL_INFO pSymInfo);
201
202 private:
203 // dereference the given symbol, i.e. return symbol which is not a
204 // pointer/reference any more
205 //
206 // if ppData != NULL, dereference the pointer as many times as we
207 // dereferenced the symbol
208 //
209 // return the tag of the dereferenced symbol
210 static SymbolTag DereferenceSymbol(PSYMBOL_INFO pSymInfo, void **ppData);
211
212 static wxString DumpField(PSYMBOL_INFO pSymInfo,
213 void *pVariable,
214 unsigned level);
215
216 static wxString DumpBaseType(BasicType bt, DWORD64 length, void *pVariable);
217
218 static wxString DumpUDT(PSYMBOL_INFO pSymInfo,
219 void *pVariable,
220 unsigned level = 0);
221 };
222
223 #endif // wxUSE_DBGHELP
224
225 #endif // _WX_MSW_DEBUGHLPH_H_
226