// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "HAL/Platform.h" // We currently only have symslib available on selected platforms. #if PLATFORM_DESKTOP #define UE_SYMSLIB_AVAILABLE 1 #else #define UE_SYMSLIB_AVAILABLE 0 #endif #if UE_SYMSLIB_AVAILABLE #include "Async/MappedFileHandle.h" #include "Async/TaskGraphInterfaces.h" #include "Common/PagedArray.h" #include "HAL/CriticalSection.h" #include "HAL/Platform.h" #include "TraceServices/Model/AnalysisSession.h" #include "TraceServices/Model/Modules.h" #include #include "symslib.h" namespace TraceServices { class FSymslibResolver { public: typedef TArray> SymbolArray; FSymslibResolver(IAnalysisSession& InSession, IResolvedSymbolFilter& InSymbolFilter); ~FSymslibResolver(); void QueueModuleLoad(const uint8* ImageId, uint32 ImageIdSize, FModule* Module); void QueueModuleReload(FModule* Module, const TCHAR* Path, TFunction ResolveOnSuccess); void QueueSymbolResolve(uint64 Address, FResolvedSymbol* Symbol); void OnAnalysisComplete(); void GetStats(IModuleProvider::FStats* OutStats) const; void EnumerateSymbolSearchPaths(TFunctionRef Callback) const; private: struct FSymsSymbol { const char* Name; }; struct FSymsUnit { SYMS_SpatialMap1D ProcMap; SYMS_String8Array FileTable; SYMS_LineTable LineTable; SYMS_SpatialMap1D LineMap; }; struct FSymsInstance { TArray Arenas; TArray Units; SYMS_SpatialMap1D UnitMap; SYMS_SpatialMap1D StrippedMap; FSymsSymbol* StrippedSymbols; uint64 DefaultBase; }; struct FModuleEntry { FModule* Module; TArray ImageId; FSymsInstance Instance; }; struct FQueuedAddress { uint64 Address; FResolvedSymbol* Target; }; enum : uint32 { MaxNameLen = 512, QueuedAddressLength = 2048, SymbolTasksInParallel = 8 }; /** * Checks if there are no modules in flight and that the queue has reached * the threshold for dispatching. Note that is up to the caller to synchronize. */ void MaybeDispatchQueuedAddresses(); /** * Dispatches the currently queued addresses to be resolved. Note that is up to the caller to synchronize. */ void DispatchQueuedAddresses(); void ResolveSymbols(TArrayView& QueuedWork); FModuleEntry* GetModuleEntry(FModule* Module) const; FModuleEntry* GetModuleForAddress(uint64 Address) const; static void UpdateResolvedSymbol(FResolvedSymbol& Symbol, ESymbolQueryResult Result, const TCHAR* Module, const TCHAR* Name, const TCHAR* File, uint16 Line); void LoadModuleTracked(FModuleEntry* Entry, FStringView OverrideSearchPath); EModuleStatus LoadModule(FModuleEntry* Entry, FStringView SearchPathView, FStringBuilderBase& OutStatusMessage) const; void ResolveSymbolTracked(uint64 Address, FResolvedSymbol& Target, class FSymbolStringAllocator& StringAllocator); bool ResolveSymbol(uint64 Address, FResolvedSymbol& Target, FSymbolStringAllocator& StringAllocator, FModuleEntry* Entry) const; void WaitForTasks(); void UpdateSessionInfo() const; mutable FRWLock ModulesLock; TPagedArray Modules; TArray SortedModules; FCriticalSection SymbolsQueueLock; TArray> ResolveQueue; std::atomic TasksInFlight; FCriticalSection CleanupLock; FGraphEventRef CleanupTask; FGraphEventRef ModuleReloadTask; std::atomic CancelTasks; mutable FRWLock CustomSymbolSearchPathsLock; TArray CustomSymbolSearchPaths; // search paths added by user from UI in the current session TArray ConfigSymbolSearchPaths; // search paths specified in environment variables and config files mutable FString Platform; mutable FString AppName; std::atomic ModulesDiscovered; std::atomic ModulesFailed; std::atomic ModulesLoaded; std::atomic SymbolBytesAllocated; std::atomic SymbolBytesWasted; IAnalysisSession& Session; IResolvedSymbolFilter& SymbolFilter; }; } // namespace TraceServices #endif //UE_SYMSLIB_AVAILABLE