1 /**
2  * ...
3  *
4  * Copyright: Copyright Benjamin Thaut 2010 - 2011.
5  * License: Distributed under the
6  *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
7  *    (See accompanying file LICENSE)
8  * Authors:   Benjamin Thaut, Sean Kelly
9  * Source:    $(DRUNTIMESRC core/sys/windows/_stacktrace.d)
10  */
11 
12 module core.sys.windows.dbghelp;
13 version (Windows):
14 
15 import core.sys.windows.winbase /+: FreeLibrary, GetProcAddress, LoadLibraryA+/;
16 import core.sys.windows.windef;
17 
18 public import core.sys.windows.dbghelp_types;
19 
20 extern(System)
21 {
22     alias BOOL         function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
23     alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
24     alias DWORD64      function(HANDLE hProcess, DWORD64 Address) GetModuleBaseProc64;
25     alias DWORD64      function(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr) TranslateAddressProc64;
26 
27     alias BOOL         function(HANDLE hProcess, PCSTR UserSearchPath, bool fInvadeProcess) SymInitializeFunc;
28     alias BOOL         function(HANDLE hProcess) SymCleanupFunc;
29     alias DWORD        function(DWORD SymOptions) SymSetOptionsFunc;
30     alias DWORD        function() SymGetOptionsFunc;
31     alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func;
32     alias BOOL         function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord,
33                                 ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess,
34                                 GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func;
35     alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINEA64 *line) SymGetLineFromAddr64Func;
36     alias DWORD64      function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func;
37     alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func;
38     alias BOOL         function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func;
39     alias DWORD        function(PCTSTR DecoratedName, PTSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
40     alias DWORD64      function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;
41     alias BOOL         function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
42     alias BOOL         function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;
43     alias BOOL         function(HANDLE hProcess, ULONG ActionCode, ulong CallbackContext, ulong UserContext) PSYMBOL_REGISTERED_CALLBACK64;
44     alias BOOL         function(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ulong UserContext) SymRegisterCallback64Func;
45     alias API_VERSION* function() ImagehlpApiVersionFunc;
46 }
47 
48 struct DbgHelp
49 {
50     SymInitializeFunc        SymInitialize;
51     SymCleanupFunc           SymCleanup;
52     StackWalk64Func          StackWalk64;
53     SymGetOptionsFunc        SymGetOptions;
54     SymSetOptionsFunc        SymSetOptions;
55     SymFunctionTableAccess64Func SymFunctionTableAccess64;
56     SymGetLineFromAddr64Func SymGetLineFromAddr64;
57     SymGetModuleBase64Func   SymGetModuleBase64;
58     SymGetModuleInfo64Func   SymGetModuleInfo64;
59     SymGetSymFromAddr64Func  SymGetSymFromAddr64;
60     UnDecorateSymbolNameFunc UnDecorateSymbolName;
61     SymLoadModule64Func      SymLoadModule64;
62     SymGetSearchPathFunc     SymGetSearchPath;
63     SymUnloadModule64Func    SymUnloadModule64;
64     SymRegisterCallback64Func SymRegisterCallback64;
65     ImagehlpApiVersionFunc   ImagehlpApiVersion;
66 
getDbgHelp67     static DbgHelp* get()
68     {
69         if ( sm_hndl != sm_hndl.init )
70             return &sm_inst;
71         if ( (sm_hndl = LoadLibraryA( "dbghelp.dll" )) != sm_hndl.init )
72         {
73             sm_inst.SymInitialize            = cast(SymInitializeFunc) GetProcAddress(sm_hndl,"SymInitialize");
74             sm_inst.SymCleanup               = cast(SymCleanupFunc) GetProcAddress(sm_hndl,"SymCleanup");
75             sm_inst.StackWalk64              = cast(StackWalk64Func) GetProcAddress(sm_hndl,"StackWalk64");
76             sm_inst.SymGetOptions            = cast(SymGetOptionsFunc) GetProcAddress(sm_hndl,"SymGetOptions");
77             sm_inst.SymSetOptions            = cast(SymSetOptionsFunc) GetProcAddress(sm_hndl,"SymSetOptions");
78             sm_inst.SymFunctionTableAccess64 = cast(SymFunctionTableAccess64Func) GetProcAddress(sm_hndl,"SymFunctionTableAccess64");
79             sm_inst.SymGetLineFromAddr64     = cast(SymGetLineFromAddr64Func) GetProcAddress(sm_hndl,"SymGetLineFromAddr64");
80             sm_inst.SymGetModuleBase64       = cast(SymGetModuleBase64Func) GetProcAddress(sm_hndl,"SymGetModuleBase64");
81             sm_inst.SymGetModuleInfo64       = cast(SymGetModuleInfo64Func) GetProcAddress(sm_hndl,"SymGetModuleInfo64");
82             sm_inst.SymGetSymFromAddr64      = cast(SymGetSymFromAddr64Func) GetProcAddress(sm_hndl,"SymGetSymFromAddr64");
83             sm_inst.SymLoadModule64          = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64");
84             sm_inst.SymGetSearchPath         = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath");
85             sm_inst.SymUnloadModule64        = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64");
86             sm_inst.SymRegisterCallback64    = cast(SymRegisterCallback64Func) GetProcAddress(sm_hndl, "SymRegisterCallback64");
87             sm_inst.ImagehlpApiVersion       = cast(ImagehlpApiVersionFunc) GetProcAddress(sm_hndl, "ImagehlpApiVersion");
88             assert( sm_inst.SymInitialize && sm_inst.SymCleanup && sm_inst.StackWalk64 && sm_inst.SymGetOptions &&
89                     sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 &&
90                     sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 &&
91                     sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath && sm_inst.SymUnloadModule64 &&
92                     sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion);
93 
94             return &sm_inst;
95         }
96         return null;
97     }
98 
~thisDbgHelp99     shared static ~this()
100     {
101         if ( sm_hndl != sm_hndl.init )
102             FreeLibrary( sm_hndl );
103     }
104 
105 private:
106     __gshared DbgHelp sm_inst;
107     __gshared HANDLE  sm_hndl;
108 }
109