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: debughlp.h 31443 2005-01-18 10:10:23Z ABX $
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#ifndef __WXWINCE__
19#include <imagehlp.h>
20#endif // __WXWINCE__
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)
52class wxDbgHelpDLL
53{
54public:
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);
149    typedef LPVOID (WINAPI *SymFunctionTableAccess_t)(HANDLE, DWORD);
150    typedef DWORD (WINAPI *SymGetModuleBase_t)(HANDLE, DWORD);
151    typedef BOOL (WINAPI *SymGetLineFromAddr_t)(HANDLE, DWORD,
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
167    #define wxDO_FOR_ALL_SYM_FUNCS(what)                                      \
168        what(SymGetOptions);                                                  \
169        what(SymSetOptions);                                                  \
170        what(SymInitialize);                                                  \
171        what(StackWalk);                                                      \
172        what(SymFromAddr);                                                    \
173        what(SymFunctionTableAccess);                                         \
174        what(SymGetModuleBase);                                               \
175        what(SymGetLineFromAddr);                                             \
176        what(SymSetContext);                                                  \
177        what(SymEnumSymbols);                                                 \
178        what(SymGetTypeInfo);                                                 \
179        what(SymCleanup);                                                     \
180        what(EnumerateLoadedModules);                                         \
181        what(MiniDumpWriteDump)
182
183    #define wxDECLARE_SYM_FUNCTION(func) static func ## _t func
184
185    wxDO_FOR_ALL_SYM_FUNCS(wxDECLARE_SYM_FUNCTION);
186
187    #undef wxDECLARE_SYM_FUNCTION
188
189    // load all functions from DLL, return true if ok
190    static bool Init();
191
192    // return the string with the error message explaining why Init() failed
193    static const wxString& GetErrorMessage();
194
195    // log error returned by the given function to debug output
196    static void LogError(const wxChar *func);
197
198    // return textual representation of the value of given symbol
199    static wxString DumpSymbol(PSYMBOL_INFO pSymInfo, void *pVariable);
200
201    // return the name of the symbol with given type index
202    static wxString GetSymbolName(PSYMBOL_INFO pSymInfo);
203
204private:
205    // dereference the given symbol, i.e. return symbol which is not a
206    // pointer/reference any more
207    //
208    // if ppData != NULL, dereference the pointer as many times as we
209    // dereferenced the symbol
210    //
211    // return the tag of the dereferenced symbol
212    static SymbolTag DereferenceSymbol(PSYMBOL_INFO pSymInfo, void **ppData);
213
214    static wxString DumpField(PSYMBOL_INFO pSymInfo,
215                              void *pVariable,
216                              unsigned level);
217
218    static wxString DumpBaseType(BasicType bt, DWORD64 length, void *pVariable);
219
220    static wxString DumpUDT(PSYMBOL_INFO pSymInfo,
221                            void *pVariable,
222                            unsigned level = 0);
223};
224
225#endif // wxUSE_DBGHELP
226
227#endif // _WX_MSW_DEBUGHLPH_H_
228
229