~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/util/windows/third_party/StackWalker/src/StackWalker.h

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __STACKWALKER_H__
 
2
#define __STACKWALKER_H__
 
3
 
 
4
#if defined(_MSC_VER)
 
5
 
 
6
/**********************************************************************
 
7
 *
 
8
 * StackWalker.h
 
9
 *
 
10
 *
 
11
 *
 
12
 * LICENSE (http://www.opensource.org/licenses/bsd-license.php)
 
13
 *
 
14
 *   Copyright (c) 2005-2009, Jochen Kalmbach
 
15
 *   All rights reserved.
 
16
 *
 
17
 *   Redistribution and use in source and binary forms, with or without modification,
 
18
 *   are permitted provided that the following conditions are met:
 
19
 *
 
20
 *   Redistributions of source code must retain the above copyright notice,
 
21
 *   this list of conditions and the following disclaimer.
 
22
 *   Redistributions in binary form must reproduce the above copyright notice,
 
23
 *   this list of conditions and the following disclaimer in the documentation
 
24
 *   and/or other materials provided with the distribution.
 
25
 *   Neither the name of Jochen Kalmbach nor the names of its contributors may be
 
26
 *   used to endorse or promote products derived from this software without
 
27
 *   specific prior written permission.
 
28
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
29
 *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
30
 *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
31
 *   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 
32
 *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
33
 *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
34
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
35
 *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
36
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
37
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
38
 *
 
39
 * **********************************************************************/
 
40
// #pragma once is supported starting with _MSC_VER 1000,
 
41
// so we need not to check the version (because we only support _MSC_VER >= 1100)!
 
42
#pragma once
 
43
 
 
44
#include <windows.h>
 
45
 
 
46
#if _MSC_VER >= 1900
 
47
#pragma warning(disable : 4091)
 
48
#endif
 
49
 
 
50
// special defines for VC5/6 (if no actual PSDK is installed):
 
51
#if _MSC_VER < 1300
 
52
typedef unsigned __int64 DWORD64, *PDWORD64;
 
53
#if defined(_WIN64)
 
54
typedef unsigned __int64 SIZE_T, *PSIZE_T;
 
55
#else
 
56
typedef unsigned long SIZE_T, *PSIZE_T;
 
57
#endif
 
58
#endif // _MSC_VER < 1300
 
59
 
 
60
class StackWalkerInternal; // forward
 
61
class StackWalker
 
62
{
 
63
public:
 
64
  typedef enum StackWalkOptions
 
65
  {
 
66
    // No addition info will be retrieved
 
67
    // (only the address is available)
 
68
    RetrieveNone = 0,
 
69
 
 
70
    // Try to get the symbol-name
 
71
    RetrieveSymbol = 1,
 
72
 
 
73
    // Try to get the line for this symbol
 
74
    RetrieveLine = 2,
 
75
 
 
76
    // Try to retrieve the module-infos
 
77
    RetrieveModuleInfo = 4,
 
78
 
 
79
    // Also retrieve the version for the DLL/EXE
 
80
    RetrieveFileVersion = 8,
 
81
 
 
82
    // Contains all the above
 
83
    RetrieveVerbose = 0xF,
 
84
 
 
85
    // Generate a "good" symbol-search-path
 
86
    SymBuildPath = 0x10,
 
87
 
 
88
    // Also use the public Microsoft-Symbol-Server
 
89
    SymUseSymSrv = 0x20,
 
90
 
 
91
    // Contains all the above "Sym"-options
 
92
    SymAll = 0x30,
 
93
 
 
94
    // Contains all options (default)
 
95
    OptionsAll = 0x3F
 
96
  } StackWalkOptions;
 
97
 
 
98
  StackWalker(int    options = OptionsAll, // 'int' is by design, to combine the enum-flags
 
99
              LPCSTR szSymPath = NULL,
 
100
              DWORD  dwProcessId = GetCurrentProcessId(),
 
101
              HANDLE hProcess = GetCurrentProcess());
 
102
  StackWalker(DWORD dwProcessId, HANDLE hProcess);
 
103
  virtual ~StackWalker();
 
104
 
 
105
  typedef BOOL(__stdcall* PReadProcessMemoryRoutine)(
 
106
      HANDLE  hProcess,
 
107
      DWORD64 qwBaseAddress,
 
108
      PVOID   lpBuffer,
 
109
      DWORD   nSize,
 
110
      LPDWORD lpNumberOfBytesRead,
 
111
      LPVOID  pUserData // optional data, which was passed in "ShowCallstack"
 
112
  );
 
113
 
 
114
  BOOL LoadModules();
 
115
 
 
116
  BOOL ShowCallstack(
 
117
      HANDLE                    hThread = GetCurrentThread(),
 
118
      const CONTEXT*            context = NULL,
 
119
      PReadProcessMemoryRoutine readMemoryFunction = NULL,
 
120
      LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback
 
121
  );
 
122
 
 
123
  BOOL ShowObject(LPVOID pObject);
 
124
 
 
125
#if _MSC_VER >= 1300
 
126
  // due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public"
 
127
  // in older compilers in order to use it... starting with VC7 we can declare it as "protected"
 
128
protected:
 
129
#endif
 
130
  enum
 
131
  {
 
132
    STACKWALK_MAX_NAMELEN = 1024
 
133
  }; // max name length for found symbols
 
134
 
 
135
protected:
 
136
  // Entry for each Callstack-Entry
 
137
  typedef struct CallstackEntry
 
138
  {
 
139
    DWORD64 offset; // if 0, we have no valid entry
 
140
    CHAR    name[STACKWALK_MAX_NAMELEN];
 
141
    CHAR    undName[STACKWALK_MAX_NAMELEN];
 
142
    CHAR    undFullName[STACKWALK_MAX_NAMELEN];
 
143
    DWORD64 offsetFromSmybol;
 
144
    DWORD   offsetFromLine;
 
145
    DWORD   lineNumber;
 
146
    CHAR    lineFileName[STACKWALK_MAX_NAMELEN];
 
147
    DWORD   symType;
 
148
    LPCSTR  symTypeString;
 
149
    CHAR    moduleName[STACKWALK_MAX_NAMELEN];
 
150
    DWORD64 baseOfImage;
 
151
    CHAR    loadedImageName[STACKWALK_MAX_NAMELEN];
 
152
  } CallstackEntry;
 
153
 
 
154
  typedef enum CallstackEntryType
 
155
  {
 
156
    firstEntry,
 
157
    nextEntry,
 
158
    lastEntry
 
159
  } CallstackEntryType;
 
160
 
 
161
  virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
 
162
  virtual void OnLoadModule(LPCSTR    img,
 
163
                            LPCSTR    mod,
 
164
                            DWORD64   baseAddr,
 
165
                            DWORD     size,
 
166
                            DWORD     result,
 
167
                            LPCSTR    symType,
 
168
                            LPCSTR    pdbName,
 
169
                            ULONGLONG fileVersion);
 
170
  virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry);
 
171
  virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
 
172
  virtual void OnOutput(LPCSTR szText);
 
173
 
 
174
  StackWalkerInternal* m_sw;
 
175
  HANDLE               m_hProcess;
 
176
  DWORD                m_dwProcessId;
 
177
  BOOL                 m_modulesLoaded;
 
178
  LPSTR                m_szSymPath;
 
179
 
 
180
  int m_options;
 
181
  int m_MaxRecursionCount;
 
182
 
 
183
  static BOOL __stdcall myReadProcMem(HANDLE  hProcess,
 
184
                                      DWORD64 qwBaseAddress,
 
185
                                      PVOID   lpBuffer,
 
186
                                      DWORD   nSize,
 
187
                                      LPDWORD lpNumberOfBytesRead);
 
188
 
 
189
  friend StackWalkerInternal;
 
190
}; // class StackWalker
 
191
 
 
192
// The "ugly" assembler-implementation is needed for systems before XP
 
193
// If you have a new PSDK and you only compile for XP and later, then you can use
 
194
// the "RtlCaptureContext"
 
195
// Currently there is no define which determines the PSDK-Version...
 
196
// So we just use the compiler-version (and assumes that the PSDK is
 
197
// the one which was installed by the VS-IDE)
 
198
 
 
199
// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later...
 
200
//       But I currently use it in x64/IA64 environments...
 
201
//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400)
 
202
 
 
203
#if defined(_M_IX86)
 
204
#ifdef CURRENT_THREAD_VIA_EXCEPTION
 
205
// TODO: The following is not a "good" implementation,
 
206
// because the callstack is only valid in the "__except" block...
 
207
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags)               \
 
208
  do                                                                            \
 
209
  {                                                                             \
 
210
    memset(&c, 0, sizeof(CONTEXT));                                             \
 
211
    EXCEPTION_POINTERS* pExp = NULL;                                            \
 
212
    __try                                                                       \
 
213
    {                                                                           \
 
214
      throw 0;                                                                  \
 
215
    }                                                                           \
 
216
    __except (((pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER   \
 
217
                                                  : EXCEPTION_EXECUTE_HANDLER)) \
 
218
    {                                                                           \
 
219
    }                                                                           \
 
220
    if (pExp != NULL)                                                           \
 
221
      memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT));                         \
 
222
    c.ContextFlags = contextFlags;                                              \
 
223
  } while (0);
 
224
#else
 
225
// clang-format off
 
226
// The following should be enough for walking the callstack...
 
227
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
 
228
  do                                                              \
 
229
  {                                                               \
 
230
    memset(&c, 0, sizeof(CONTEXT));                               \
 
231
    c.ContextFlags = contextFlags;                                \
 
232
    __asm    call x                                               \
 
233
    __asm x: pop eax                                              \
 
234
    __asm    mov c.Eip, eax                                       \
 
235
    __asm    mov c.Ebp, ebp                                       \
 
236
    __asm    mov c.Esp, esp                                       \
 
237
  } while (0)
 
238
// clang-format on
 
239
#endif
 
240
 
 
241
#else
 
242
 
 
243
// The following is defined for x86 (XP and higher), x64 and IA64:
 
244
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
 
245
  do                                                              \
 
246
  {                                                               \
 
247
    memset(&c, 0, sizeof(CONTEXT));                               \
 
248
    c.ContextFlags = contextFlags;                                \
 
249
    RtlCaptureContext(&c);                                        \
 
250
  } while (0)
 
251
#endif
 
252
 
 
253
#endif //defined(_MSC_VER)
 
254
 
 
255
#endif // __STACKWALKER_H__