Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
GenericPlatformStackWalk.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "Containers/Map.h"
7#include "Containers/UnrealString.h"
8#include "CoreTypes.h"
9#include "UObject/NameTypes.h"
10
11class FName;
13struct FProcHandle;
15
16/**
17 * This is used to capture all of the module information needed to load pdb's.
18 * @todo, the memory profiler should not be using this as platform agnostic
19 */
21{
23 uint32 ImageSize;
25 TCHAR ModuleName[32];
26 TCHAR ImageName[256];
27 TCHAR LoadedImageName[256];
28 uint32 PdbSig;
29 uint32 PdbAge;
30 struct
31 {
32 unsigned long Data1;
33 unsigned short Data2;
34 unsigned short Data3;
35 unsigned char Data4[8];
36 } PdbSig70;
37};
38
39/**
40 * Symbol information associated with a program counter. ANSI version.
41 */
42struct FProgramCounterSymbolInfo final
43{
44 enum
45 {
46 /** Length of the string used to store the symbol's names, including the trailing character. */
48 };
49
50 /** Module name. */
52
53 /** Function name. */
55
56 /** Filename. */
58
59 /** Line number in file. */
61
62 /** Symbol displacement of address. */
64
65 /** Program counter offset into module. */
67
68 /** Program counter. */
70
71 /** Default constructor. */
73};
74
76{
77 /** Module name. */
79
80 /** Function name. */
82
83 /** Filename. */
85
86 /** Line number in file. */
87 uint32 LineNumber;
88
89 /** Symbol displacement of address. */
91
92 /** Program counter offset into module. */
94
95 /** Program counter. */
97
98 /** Default constructor. */
99 FProgramCounterSymbolInfoEx(FString InModuleName = "", FString InFunctionName = "", FString InFilename = "", uint32 InLineNumber = 0, uint64 InSymbolDisplacement = 0, uint64 InOffsetInModule = 0, uint64 InProgramCounter = 0);
100};
101
102/**
103 * Generic implementation for most platforms
104 */
106{
108
110 {
111 enum
112 {
113 /** Default value (empty set of flags). */
115
116 /** Used when preferring speed over more information. Platform-specific, may be ignored, or may result in non-symbolicated callstacks or missing some other information. */
117 FastStackWalk = (1 << 0),
118
119 /** This is a set of flags that will be passed when unwinding the callstack for ensure(). */
121 };
122 };
123
124 /**
125 * Initializes options related to stack walking from ini, i.e. how detailed the stack walking should be, performance settings etc.
126 */
127 static void Init();
128
129 /**
130 * Initializes stack traversal and symbol. Must be called before any other stack/symbol functions. Safe to reenter.
131 */
132 static bool InitStackWalking()
133 {
134 return 1;
135 }
136
137 /**
138 * Like InitStackWalking but initializes stack walking for another process.
139 * @param Process Process that is going to be queried
140 * @return True if successful, false otherwise.
141 */
142 static bool InitStackWalkingForProcess(const FProcHandle& Process)
143 {
144 return false;
145 }
146
147 /**
148 * Converts the passed in program counter address to a human readable string and appends it to the passed in one.
149 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
150 * @warning: Please, do not override this method. Can't be modified or altered without notice.
151 *
152 * This method is the same for all platforms to simplify parsing by the crash processor.
153 *
154 * Example formatted line:
155 *
156 * UE4Editor_Core!FOutputDeviceWindowsError::Serialize() (0xddf1bae5) + 620 bytes [\engine\source\runtime\core\private\windows\windowsplatformoutputdevices.cpp:110]
157 * ModuleName!FunctionName (ProgramCounter) + offset bytes [StrippedFilepath:LineNumber]
158 *
159 * @param CurrentCallDepth Depth of the call, if known (-1 if not - note that some platforms may not return meaningful information in the latter case)
160 * @param ProgramCounter Address to look symbol information up for
161 * @param HumanReadableString String to concatenate information with
162 * @param HumanReadableStringSize size of string in characters
163 * @param Context Pointer to crash context, if any
164 * @return true if the symbol was found, otherwise false
165 */
166 static bool ProgramCounterToHumanReadableString( int32 CurrentCallDepth, uint64 ProgramCounter, ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, FGenericCrashContext* Context = nullptr );
167
168 /**
169 * Converts the passed in symbol information to a human readable string and appends it to the passed in one.
170 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
171 * @warning: Please, do not override this method. Can't be modified or altered without notice.
172 *
173 * This method is the same for all platforms to simplify parsing by the crash processor.
174 *
175 * Example formatted line:
176 *
177 * UE4Editor_Core!FOutputDeviceWindowsError::Serialize() (0xddf1bae5) + 620 bytes [\engine\source\runtime\core\private\windows\windowsplatformoutputdevices.cpp:110]
178 * ModuleName!FunctionName (ProgramCounter) + offset bytes [StrippedFilepath:LineNumber]
179 *
180 * @param SymbolInfo Symbol information
181 * @param HumanReadableString String to concatenate information with
182 * @param HumanReadableStringSize size of string in characters
183 * @param Context Pointer to crash context, if any
184 * @return true if the symbol was found, otherwise false
185 */
186 static bool SymbolInfoToHumanReadableString( const FProgramCounterSymbolInfo& SymbolInfo, ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize );
187
188 /** Same as above, but can be used with external applications. */
189 static bool SymbolInfoToHumanReadableStringEx( const FProgramCounterSymbolInfoEx& SymbolInfo, FString& out_HumanReadableString );
190
191 /**
192 * Converts the passed in program counter address to a symbol info struct, filling in module and filename, line number and displacement.
193 * @warning: The code assumes that the destination strings are big enough
194 *
195 * @param ProgramCounter Address to look symbol information up for
196 * @param out_SymbolInfo Symbol information associated with program counter
197 */
198 static void ProgramCounterToSymbolInfo( uint64 ProgramCounter, FProgramCounterSymbolInfo& out_SymbolInfo)
199 {
200 out_SymbolInfo.ProgramCounter = ProgramCounter;
201 }
202
203 /** Same as above, but can be used with external applications since it doesn't re-initialize the active process. */
204 static void ProgramCounterToSymbolInfoEx( uint64 ProgramCounter, FProgramCounterSymbolInfoEx& out_SymbolInfo)
205 {
206 out_SymbolInfo.ProgramCounter = ProgramCounter;
207 }
208
209 /**
210 * Capture a stack backtrace and optionally use the passed in exception pointers.
211 *
212 * @param BackTrace [out] Pointer to array to take backtrace
213 * @param MaxDepth Entries in BackTrace array
214 * @param Context Optional thread context information
215 */
216 static uint32 CaptureStackBackTrace( uint64* BackTrace, uint32 MaxDepth, void* Context = nullptr );
217
218 /**
219 * Capture a stack backtrace for a specific thread.
220 *
221 * @param ThreadId ID of the thread to trace
222 * @param BackTrace [out] Pointer to array to take backtrace
223 * @param MaxDepth Entries in BackTrace array
224 * @param Context Optional thread context information
225 */
226 static uint32 CaptureThreadStackBackTrace(uint64 ThreadId, uint64* BackTrace, uint32 MaxDepth, void* Context = nullptr);
227
228 /**
229 * Walks the stack and appends the human readable string to the passed in one.
230 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
231 *
232 * @param HumanReadableString String to concatenate information with
233 * @param HumanReadableStringSize size of string in characters
234 * @param IgnoreCount Number of stack entries to ignore (some are guaranteed to be in the stack walking code)
235 * @param Context Optional thread context information
236 */
237 FORCENOINLINE static void StackWalkAndDump( ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, void* Context = nullptr ); // FORCENOINLINE so it can be counted during StackTrace
238
239 /**
240 * Walks the stack and appends the human readable string to the passed in one.
241 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
242 *
243 * @param HumanReadableString String to concatenate information with
244 * @param HumanReadableStringSize size of string in characters
245 * @param ProgramCounter Instruction address that should be at the top of the stack
246 * @param Context Optional thread context information
247 */
248 static void StackWalkAndDump( ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, void* ProgramCounter, void* Context = nullptr );
249
250 /**
251 * Walks the stack and updates the Stack array with the symbol information for each line in the stack.
252 *
253 * @param IgnoreCount Number of stack entries to ignore (some are guaranteed to be in the stack walking code)
254 * @param MaxDepth The maximum depth to trace, can't be more than 100, offset from IgnoreCount.
255 * @param Context Optional thread context information
256 *
257 * @return The stack of symbols to return.
258 */
260
261 /**
262 * Walks the stack for the specified thread and appends the human readable string to the passed in one.
263 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
264 *
265 * @param HumanReadableString String to concatenate information with
266 * @param HumanReadableStringSize size of string in characters
267 * @param IgnoreCount Number of stack entries to ignore (some are guaranteed to be in the stack walking code)
268 * @param ThreadId ThreadId to walk the strack for.
269 */
270 static void ThreadStackWalkAndDump(ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, uint32 ThreadId)
271 {
272 }
273
274 /**
275 * Walks the stack and appends the human readable string to the passed in one.
276 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
277 *
278 * @param HumanReadableString String to concatenate information with
279 * @param HumanReadableStringSize size of string in characters
280 * @param IgnoreCount Number of stack entries to ignore (some are guaranteed to be in the stack walking code)
281 * @param Flags Used to pass additional information (see StackWalkFlags)
282 * @param Context Optional thread context information
283 */
284 static void StackWalkAndDumpEx( ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, uint32 Flags, void* Context = nullptr );
285 /**
286 * Walks the stack and appends the human readable string to the passed in one.
287 * @warning: The code assumes that HumanReadableString is large enough to contain the information.
288 *
289 * @param HumanReadableString String to concatenate information with
290 * @param HumanReadableStringSize size of string in characters
291 * @param ProgramCounter Instruction address that should be at the top of the stack
292 * @param Flags Used to pass additional information (see StackWalkFlags)
293 * @param Context Optional thread context information
294 */
295 static void StackWalkAndDumpEx( ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, void* ProgramCounter, uint32 Flags, void* Context = nullptr );
296
297 /**
298 * Returns the number of modules loaded by the currently running process.
299 */
301 {
302 return 0;
303 }
304
305 /**
306 * Gets the signature for every module loaded by the currently running process.
307 *
308 * @param ModuleSignatures An array to retrieve the module signatures.
309 * @param ModuleSignaturesSize The size of the array pointed to by ModuleSignatures.
310 *
311 * @return The number of modules copied into ModuleSignatures
312 */
313 FORCEINLINE static int32 GetProcessModuleSignatures(FStackWalkModuleInfo *ModuleSignatures, const int32 ModuleSignaturesSize)
314 {
315 return 0;
316 }
317
318 /**
319 * Gets the meta-data associated with all symbols of this target.
320 * This may include things that are needed to perform further offline processing of symbol information (eg, the source binary).
321 *
322 * @return A map containing the meta-data (if any).
323 */
325
326protected:
327
328 /** Returns true if non-monolithic builds should produce full callstacks in the log (and load all debug symbols) */
330
331};
#define FORCENOINLINE
Definition Platform.h:647
#define FORCEINLINE
Definition Platform.h:644
static void StackWalkAndDumpEx(ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, uint32 Flags, void *Context=nullptr)
static TArray< FProgramCounterSymbolInfo > GetStack(int32 IgnoreCount, int32 MaxDepth=100, void *Context=nullptr)
static bool SymbolInfoToHumanReadableStringEx(const FProgramCounterSymbolInfoEx &SymbolInfo, FString &out_HumanReadableString)
FGenericPlatformStackWalk Base
static bool SymbolInfoToHumanReadableString(const FProgramCounterSymbolInfo &SymbolInfo, ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize)
static bool InitStackWalkingForProcess(const FProcHandle &Process)
static void StackWalkAndDumpEx(ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize, void *ProgramCounter, uint32 Flags, void *Context=nullptr)
static void ThreadStackWalkAndDump(ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, uint32 ThreadId)
static void ProgramCounterToSymbolInfo(uint64 ProgramCounter, FProgramCounterSymbolInfo &out_SymbolInfo)
static FORCEINLINE int32 GetProcessModuleCount()
static TMap< FName, FString > GetSymbolMetaData()
static void ProgramCounterToSymbolInfoEx(uint64 ProgramCounter, FProgramCounterSymbolInfoEx &out_SymbolInfo)
static bool ProgramCounterToHumanReadableString(int32 CurrentCallDepth, uint64 ProgramCounter, ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize, FGenericCrashContext *Context=nullptr)
static uint32 CaptureThreadStackBackTrace(uint64 ThreadId, uint64 *BackTrace, uint32 MaxDepth, void *Context=nullptr)
static FORCEINLINE int32 GetProcessModuleSignatures(FStackWalkModuleInfo *ModuleSignatures, const int32 ModuleSignaturesSize)
static FORCENOINLINE void StackWalkAndDump(ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, void *Context=nullptr)
static void StackWalkAndDump(ANSICHAR *HumanReadableString, SIZE_T HumanReadableStringSize, void *ProgramCounter, void *Context=nullptr)
static bool WantsDetailedCallstacksInNonMonolithicBuilds()
FProgramCounterSymbolInfoEx(FString InModuleName="", FString InFunctionName="", FString InFilename="", uint32 InLineNumber=0, uint64 InSymbolDisplacement=0, uint64 InOffsetInModule=0, uint64 InProgramCounter=0)
ANSICHAR Filename[MAX_NAME_LENGTH]
ANSICHAR ModuleName[MAX_NAME_LENGTH]
ANSICHAR FunctionName[MAX_NAME_LENGTH]