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