#pragma once #include "DebugCommon.h" #include "Compiler/MemReporter.h" #include "BeefySysLib/util/HashSet.h" #include NS_BF_BEGIN class DebugManager; class BfAutoComplete; enum DbgHitCountBreakKind : int8 { DbgHitCountBreakKind_None, DbgHitCountBreakKind_Equals, DbgHitCountBreakKind_GreaterEquals, DbgHitCountBreakKind_Multiple }; class Breakpoint { public: String mFilePath; int mRequestedLineNum; int mLineNum; int mColumn; int mInstrOffset; int mPendingHotBindIdx; int mHitCount; int mTargetHitCount; DbgHitCountBreakKind mHitCountBreakKind; String mLogging; bool mBreakAfterLogging; intptr mThreadId; String mSymbolName; Breakpoint* mHead; Breakpoint* mLinkedSibling; // For things like templates with multiple imps on same source line bool mIsLinkedSibling; // Not in breakpoint list public: Breakpoint() { mRequestedLineNum = -1; mLineNum = -1; mColumn = -1; mInstrOffset = 0; mPendingHotBindIdx = -1; mHitCount = 0; mTargetHitCount = 0; mHitCountBreakKind = DbgHitCountBreakKind_None; mThreadId = -1; mHead = NULL; mLinkedSibling = NULL; mIsLinkedSibling = false; mBreakAfterLogging = false; } virtual uintptr GetAddr() = 0; virtual bool IsMemoryBreakpointBound() = 0; }; enum DwDisplayType : int8 { DwDisplayType_NotSpecified, DwDisplayType_Decimal, DwDisplayType_HexLower, DwDisplayType_HexUpper, DwDisplayType_Char, DwDisplayType_Ascii, DwDisplayType_Utf8, DwDisplayType_Utf16, DwDisplayType_Utf32, }; enum DwIntDisplayType : int8 { DwIntDisplayType_Default, DwIntDisplayType_Decimal, DwIntDisplayType_HexadecimalUpper, DwIntDisplayType_Binary, DwIntDisplayType_Octal, DwIntDisplayType_HexadecimalLower, }; enum DwMmDisplayType : int8 { DwMmDisplayType_Default, DwMmDisplayType_Byte, DwMmDisplayType_Short, DwMmDisplayType_Int, DwMmDisplayType_Long, DwMmDisplayType_Float, DwMmDisplayType_Double }; enum DwEvalExpressionFlags : int16 { DwEvalExpressionFlag_None = 0, DwEvalExpressionFlag_FullPrecision = 0x01, DwEvalExpressionFlag_ValidateOnly = 0x02, DwEvalExpressionFlag_DeselectCallStackIdx = 0x04, DwEvalExpressionFlag_AllowSideEffects = 0x08, DwEvalExpressionFlag_AllowCalls = 0x10, DwEvalExpressionFlag_MemoryAddress = 0x20, DwEvalExpressionFlag_MemoryWatch = 0x40, DwEvalExpressionFlag_Symbol = 0x80, DwEvalExpressionFlag_StepIntoCalls = 0x100, }; struct DwDisplayInfo { DwIntDisplayType mIntDisplayType; DwMmDisplayType mMmDisplayType; DwDisplayInfo() { mIntDisplayType = DwIntDisplayType_Default; mMmDisplayType = DwMmDisplayType_Default; } }; enum RunState { RunState_NotStarted, RunState_Running, RunState_Running_ToTempBreakpoint, RunState_Paused, RunState_Breakpoint, RunState_DebugEval, RunState_DebugEval_Done, RunState_HotStep, RunState_Exception, RunState_Terminating, RunState_Terminated, RunState_SearchingSymSrv, RunState_HotResolve }; enum DebuggerResult { DebuggerResult_Ok, DebuggerResult_UnknownError, DebuggerResult_CannotOpen, DebuggerResult_WrongBitSize, }; enum BfDbgAttachFlags : uint8 { BfDbgAttachFlag_None = 0, BfDbgAttachFlag_ShutdownOnExit = 1 }; enum BfSymSrvFlags : uint8 { BfSymSrvFlag_None = 0, BfSymSrvFlag_Disable = 1, BfSymSrvFlag_TempCache = 2, // For testing - set up clean temporary cache }; enum DbgHotResolveFlags : uint8 { DbgHotResolveFlag_None = 0, DbgHotResolveFlag_ActiveMethods = 1, DbgHotResolveFlag_Allocations = 2, }; enum DbgMemoryFlags : uint8 { DbgMemoryFlags_None = 0, DbgMemoryFlags_Read = 1, DbgMemoryFlags_Write = 2, DbgMemoryFlags_Execute = 4 }; class DbgModuleMemoryCache { public: public: uintptr mAddr; int mSize; int mBlockSize; uint8** mBlocks; DbgMemoryFlags* mFlags; int mBlockCount; bool mOwns; public: DbgModuleMemoryCache(uintptr addr, int size); //DbgModuleMemoryCache(uintptr addr, uint8* data, int size, bool makeCopy); ~DbgModuleMemoryCache(); DbgMemoryFlags Read(uintptr addr, uint8* data, int size); void ReportMemory(MemReporter* memReporter); }; class DbgHotResolveData { public: Array mTypeData; Beefy::HashSet mBeefCallStackEntries; }; class Profiler; class Debugger { public: DebugManager* mDebugManager; RunState mRunState; DbgHotResolveData* mHotResolveData; bool mHadImageFindError; public: Debugger() { mDebugManager = NULL; mRunState = RunState_NotStarted; mHotResolveData = NULL; mHadImageFindError = false; } virtual ~Debugger() { delete mHotResolveData; } virtual void OutputMessage(const StringImpl& msg) = 0; virtual void OutputRawMessage(const StringImpl& msg) = 0; virtual int GetAddrSize() = 0; virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) = 0; virtual void OpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array& envBlock) = 0; virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) = 0; virtual void Run() = 0; virtual void HotLoad(const Array& objectFiles, int hotIdx) = 0; virtual void InitiateHotResolve(DbgHotResolveFlags flags) = 0; virtual void Update() = 0; virtual void ContinueDebugEvent() = 0; virtual void ForegroundTarget() = 0; virtual Breakpoint* CreateBreakpoint(const StringImpl& fileName, int lineNum, int wantColumn, int instrOffset) = 0; virtual Breakpoint* CreateMemoryBreakpoint(intptr addr, int byteCount) = 0; virtual Breakpoint* CreateSymbolBreakpoint(const StringImpl& symbolName) = 0; virtual Breakpoint* CreateAddressBreakpoint(intptr address) = 0; virtual void CheckBreakpoint(Breakpoint* breakpoint) = 0; virtual void HotBindBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int hotIdx) = 0; virtual void DeleteBreakpoint(Breakpoint* wdBreakpoint) = 0; virtual void DetachBreakpoint(Breakpoint* wdBreakpoint) = 0; virtual void MoveBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int wantColumn, bool rebindNow) = 0; virtual void MoveMemoryBreakpoint(Breakpoint* wdBreakpoint, intptr addr, int byteCount) = 0; virtual void DisableBreakpoint(Breakpoint* wdBreakpoint) = 0; virtual void SetBreakpointCondition(Breakpoint* wdBreakpoint, const StringImpl& condition) = 0; virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) = 0; virtual Breakpoint* FindBreakpointAt(intptr address) = 0; virtual Breakpoint* GetActiveBreakpoint() = 0; virtual void BreakAll() = 0; virtual bool TryRunContinue() = 0; virtual void StepInto(bool inAssembly) = 0; virtual void StepIntoSpecific(intptr addr) = 0; virtual void StepOver(bool inAssembly) = 0; virtual void StepOut(bool inAssembly) = 0; virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) = 0; //virtual DbgTypedValue GetRegister(const StringImpl& regName, CPURegisters* registers, Array* regForms = NULL) = 0; virtual String Evaluate(const StringImpl& expr, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) = 0; virtual String EvaluateContinue() = 0; virtual void EvaluateContinueKeep() = 0; virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) = 0; virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) = 0; virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) = 0; virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) = 0; virtual String GetAutoLocals(int callStackIdx, bool showRegs) = 0; virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) = 0; virtual String GetThreadInfo() = 0; virtual void SetActiveThread(int threadId) = 0; virtual int GetActiveThread() = 0; virtual void FreezeThread(int threadId) = 0; virtual void ThawThread(int threadId) = 0; virtual bool IsActiveThreadWaiting() = 0; virtual void ClearCallStack() = 0; virtual void UpdateCallStack(bool slowEarlyOut = true) = 0; virtual int GetCallStackCount() = 0; virtual int GetRequestedStackFrameIdx() = 0; virtual int GetBreakStackFrameIdx() = 0; virtual bool ReadMemory(intptr address, uint64 length, void* dest, bool local = false) = 0; virtual bool WriteMemory(intptr address, void* src, uint64 length) = 0; virtual DbgMemoryFlags GetMemoryFlags(intptr address) = 0; virtual void UpdateRegisterUsage(int stackFrameIdx) = 0; virtual void UpdateCallStackMethod(int stackFrameIdx) = 0; virtual void GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) = 0; virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) = 0; virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) = 0; virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) = 0; virtual int GetJmpState(int stackFrameIdx) = 0; virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) = 0; virtual String GetStackMethodOwner(int stackFrameIdx, int& language) = 0; virtual String FindCodeAddresses(const StringImpl& fileName, int line, int column, bool allowAutoResolve) = 0; virtual String GetAddressSourceLocation(intptr address) = 0; virtual String GetAddressSymbolName(intptr address, bool demangle) = 0; virtual String DisassembleAtRaw(intptr address) = 0; virtual String DisassembleAt(intptr address) = 0; virtual String FindLineCallAddresses(intptr address) = 0; virtual String GetCurrentException() = 0; virtual String GetModulesInfo() = 0; virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) = 0; virtual void CancelSymSrv() = 0; virtual bool HasPendingDebugLoads() = 0; virtual int LoadDebugInfoForModule(const StringImpl& moduleName) = 0; virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName) = 0; virtual void StopDebugging() = 0; virtual void Terminate() = 0; virtual void Detach() = 0; virtual Profiler* StartProfiling() = 0; virtual Profiler* PopProfiler() = 0; // Profiler requested by target program virtual void ReportMemory(MemReporter* memReporter) = 0; virtual bool IsOnDemandDebugger() = 0; }; class Profiler { public: String mDescription; int mSamplesPerSecond; intptr mTargetThreadId; public: Profiler() { mSamplesPerSecond = -1; mTargetThreadId = 0; } virtual ~Profiler() {} virtual void Start() = 0; virtual void Stop() = 0; virtual void Clear() = 0; virtual bool IsSampling() = 0; virtual String GetOverview() = 0; virtual String GetThreadList() = 0; virtual String GetCallTree(int threadId, bool reverse) = 0; }; NS_BF_END