RCFProto
 All Classes Functions Typedefs
CallStack.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 // This call stack implementation is used by CMemLeakDetect. It is faster than
20 // other code I've tried, however it does not appear to work correctly in release
21 // builds, and does not work at all in x64.
22 
23 // StackWalker from CodeProject works in debug/release, x86/x64, but is slow (too
24 // slow to be called on every memory allocation).
25 
26 #pragma once
27 
28 #include <windows.h>
29 #include <dbghelp.h>
30 #include <crtdbg.h>
31 
32 // if you want to use the custom stackwalker otherwise
33 // comment this line out
34 #define MLD_CUSTOMSTACKWALK 1
35 //
36 #define MLD_MAX_NAME_LENGTH 256
37 #define MLD_MAX_TRACEINFO 256
38 #define MLD_TRACEINFO_EMPTY _T("")
39 #define MLD_TRACEINFO_NOSYMBOL _T("?(?)")
40 
41 #ifdef MLD_CUSTOMSTACKWALK
42 #define MLD_STACKWALKER symStackTrace2
43 #else
44 #define MLD_STACKWALKER symStackTrace
45 #endif
46 
47 #if !defined(_MSC_VER) || defined(_WIN64)
48 
49 class CallStack
50 {
51 public:
52 
53  void capture()
54  {
55  }
56 
57  std::basic_string<TCHAR> toString()
58  {
59  return _T("<Call stack unavailable>");
60  }
61 
62  static void initSymbols()
63  {
64  }
65 
66  static void deinitSymbols()
67  {
68  }
69 };
70 
71 #else
72 
73 typedef DWORD ADDR;
74 
75 struct CallStackFrameEntry {
76  ADDRESS addrPC;
77  ADDRESS addrFrame;
78 };
79 
80 class CallStack
81 {
82 public:
83 
84  CallStack()
85  {
86  memset(traceinfo, 0, MLD_MAX_TRACEINFO * sizeof(CallStackFrameEntry));
87  }
88 
89  void capture();
90  std::basic_string<TCHAR> toString();
91 
92  static void initSymbols();
93  static void deinitSymbols();
94 
95 private:
96 
97  friend class CMemLeakDetect;
98 
99  CallStackFrameEntry traceinfo[MLD_MAX_TRACEINFO];
100 
101  static HANDLE m_hProcess;
102  static PIMAGEHLP_SYMBOL m_pSymbol;
103  static DWORD m_dwsymBufSize;
104 
105  static BOOL initSymInfo(TCHAR* lpUserPath);
106  static BOOL cleanupSymInfo();
107  static void symbolPaths( TCHAR* lpszSymbolPaths, UINT BufSizeTCHARs);
108  static void symStackTrace(CallStackFrameEntry* pStacktrace);
109  static void symStackTrace2(CallStackFrameEntry* pStacktrace);
110  static BOOL symFunctionInfoFromAddresses(ULONG fnAddress, ULONG stackAddress, TCHAR* lpszSymbol, UINT BufSizeTCHARs);
111  static BOOL symSourceInfoFromAddress(UINT address, TCHAR* lpszSourceInfo, UINT BufSizeTCHARs);
112  static BOOL symModuleNameFromAddress(UINT address, TCHAR* lpszModule, UINT BufSizeTCHARs);
113 };
114 
115 #endif