#pragma once #include "BeefySysLib/Common.h" #include "BeefySysLib/Util/PerfTimer.h" #include "DbgSymSrv.h" #include "DebugTarget.h" #include "DbgExprEvaluator.h" #include "Debugger.h" #include "HotHeap.h" #include "COFF.h" namespace Beefy { class BfSystem; class BfReducer; class BfPassInstance; class DebugManager; class DebugVisualizers; class DebugVisualizerEntry; }; NS_BF_DBG_BEGIN class DbgProfiler; class DbgModule; class DbgSrcFile; class DbgLineData; class X86; class HotHeap; #ifdef BF_DBG_32 #ifdef BF32 #define BF_CONTEXT CONTEXT #define BF_GetThreadContext GetThreadContext #define BF_SetThreadContext SetThreadContext #define BF_CONTEXT_CONTROL CONTEXT_CONTROL #define BF_CONTEXT_INTEGER CONTEXT_INTEGER #define BF_CONTEXT_SEGMENTS CONTEXT_SEGMENTS #define BF_CONTEXT_FLOATING_POINT CONTEXT_FLOATING_POINT #define BF_CONTEXT_DEBUG_REGISTERS CONTEXT_DEBUG_REGISTERS #define BF_CONTEXT_EXTENDED_REGISTERS CONTEXT_EXTENDED_REGISTERS #define BF_CONTEXT_EXCEPTION_REQUEST CONTEXT_EXCEPTION_REQUEST #define BF_CONTEXT_EXCEPTION_ACTIVE CONTEXT_EXCEPTION_ACTIVE #define BF_CONTEXT_SERVICE_ACTIVE CONTEXT_SERVICE_ACTIVE #define BF_CONTEXT_ALL CONTEXT_ALL #define BF_CONTEXT_SP(ctx) ctx.Esp #define BF_CONTEXT_BP(ctx) ctx.Ebp #define BF_CONTEXT_IP(ctx) ctx.Eip #define BF_CONTEXT_FLTDATA(ctx) ctx.FloatSave.RegisterArea #define BF_CONTEXT_XMMDATA(ctx) &ctx.ExtendedRegisters[160] #else #define BF_CONTEXT WOW64_CONTEXT #define BF_GetThreadContext Wow64GetThreadContext #define BF_SetThreadContext Wow64SetThreadContext #define BF_CONTEXT_CONTROL WOW64_CONTEXT_CONTROL #define BF_CONTEXT_INTEGER WOW64_CONTEXT_INTEGER #define BF_CONTEXT_SEGMENTS WOW64_CONTEXT_SEGMENTS #define BF_CONTEXT_FLOATING_POINT WOW64_CONTEXT_FLOATING_POINT #define BF_CONTEXT_DEBUG_REGISTERS WOW64_CONTEXT_DEBUG_REGISTERS #define BF_CONTEXT_EXTENDED_REGISTERS WOW64_CONTEXT_EXTENDED_REGISTERS #define BF_CONTEXT_EXCEPTION_REQUEST WOW64_CONTEXT_EXCEPTION_REQUEST #define BF_CONTEXT_EXCEPTION_ACTIVE WOW64_CONTEXT_EXCEPTION_ACTIVE #define BF_CONTEXT_SERVICE_ACTIVE WOW64_CONTEXT_SERVICE_ACTIVE #define BF_CONTEXT_ALL WOW64_CONTEXT_ALL #define BF_CONTEXT_SP(ctx) ctx.Esp #define BF_CONTEXT_BP(ctx) ctx.Ebp #define BF_CONTEXT_IP(ctx) ctx.Eip #define BF_CONTEXT_FLTDATA(ctx) ctx.FloatSave.RegisterArea #define BF_CONTEXT_XMMDATA(ctx) &ctx.ExtendedRegisters[160] #endif #else // BG_DBG_64 #define BF_CONTEXT CONTEXT #define BF_GetThreadContext GetThreadContext #define BF_SetThreadContext SetThreadContext #define BF_CONTEXT_CONTROL CONTEXT_CONTROL #define BF_CONTEXT_INTEGER CONTEXT_INTEGER #define BF_CONTEXT_SEGMENTS CONTEXT_SEGMENTS #define BF_CONTEXT_FLOATING_POINT CONTEXT_FLOATING_POINT #define BF_CONTEXT_DEBUG_REGISTERS CONTEXT_DEBUG_REGISTERS #define BF_CONTEXT_EXTENDED_REGISTERS 0 #define BF_CONTEXT_EXCEPTION_REQUEST CONTEXT_EXCEPTION_REQUEST #define BF_CONTEXT_EXCEPTION_ACTIVE CONTEXT_EXCEPTION_ACTIVE #define BF_CONTEXT_SERVICE_ACTIVE CONTEXT_SERVICE_ACTIVE #define BF_CONTEXT_ALL CONTEXT_ALL #define BF_CONTEXT_SP(ctx) ctx.Rsp #define BF_CONTEXT_BP(ctx) ctx.Rbp #define BF_CONTEXT_IP(ctx) ctx.Rip #define BF_CONTEXT_FLTDATA(ctx) ctx.FltSave.FloatRegisters #define BF_CONTEXT_XMMDATA(ctx) ctx.FltSave.XmmRegisters #endif enum BreakpointType { BreakpointType_User, BreakpointType_Stepping }; struct DwFormatInfo; class DbgEvaluationContext { public: BfParser* mParser; BfReducer* mReducer; BfPassInstance* mPassInstance; DbgExprEvaluator* mDbgExprEvaluator; BfExpression* mExprNode; public: DbgEvaluationContext(WinDebugger* winDebugger, DbgModule* dbgModule, const StringImpl& expr, DwFormatInfo* formatInfo = NULL, DbgTypedValue contextValue = DbgTypedValue()); DbgEvaluationContext(WinDebugger* winDebugger, DbgCompileUnit* dbgCompileUnit, const StringImpl& expr, DwFormatInfo* formatInfo = NULL, DbgTypedValue contextValue = DbgTypedValue()); void Init(WinDebugger* winDebugger, DbgModule* dbgModule, const StringImpl& expr, DwFormatInfo* formatInfo = NULL, DbgTypedValue contextValue = DbgTypedValue()); bool HasExpression(); ~DbgEvaluationContext(); DbgTypedValue EvaluateInContext(DbgTypedValue contextTypedValue); String GetErrorStr(); bool HadError(); }; class WdBreakpointCondition { public: DbgEvaluationContext* mDbgEvaluationContext; String mExpr; ~WdBreakpointCondition(); }; class WdMemoryBreakpointInfo { public: addr_target mMemoryAddress; int mByteCount; String mReferenceName; int8 mMemoryWatchSlotBitmap; WdMemoryBreakpointInfo() { mMemoryAddress = 0; mByteCount = 0; mMemoryWatchSlotBitmap = 0; } }; class WdBreakpoint : public Breakpoint { public: WdMemoryBreakpointInfo* mMemoryBreakpointInfo; addr_target mAddr; DbgSrcFile* mSrcFile; DbgLineDataEx mLineData; WdBreakpointCondition* mCondition; BreakpointType mBreakpointType; public: WdBreakpoint() { mMemoryBreakpointInfo = NULL; mAddr = 0; mSrcFile = NULL; mLineData = DbgLineDataEx(); mCondition = NULL; mBreakpointType = BreakpointType_User; } virtual uintptr GetAddr() override { return (uintptr)mAddr; } virtual bool IsMemoryBreakpointBound() override { return (mMemoryBreakpointInfo != NULL) && (mMemoryBreakpointInfo->mMemoryWatchSlotBitmap != 0); } WdBreakpoint* GetHeadBreakpoint() { if (mHead != NULL) return (WdBreakpoint*)mHead; return this; } }; enum StepType { StepType_None, StepType_StepInto, StepType_StepInto_Unfiltered, StepType_StepInto_UnfilteredSingle, StepType_StepOver, StepType_StepOut, StepType_StepOut_ThenInto, // For supporting step filters StepType_StepOut_NoFrame, StepType_StepOut_Inline, StepType_ToTempBreakpoint }; class WdStackFrame { public: CPURegisters mRegisters; bool mIsStart; bool mIsEnd; bool mInInlineMethod; bool mInInlineCall; // Means the frame above us is inlined DbgSubprogram* mSubProgram; bool mHasGottenSubProgram; Array mRegForms; public: WdStackFrame() { mSubProgram = NULL; mHasGottenSubProgram = false; mIsStart = true; mIsEnd = false; mInInlineMethod = false; mInInlineCall = false; } addr_target GetSourcePC() { // 'PC' is return address of call in these cases, so subtract 1 for cases where // we want to bring it back into the calling block range (note that this doesn't // properly determine the actual starting address of the call instruction, though) if ((!mIsStart) && (!mInInlineCall)) return mRegisters.GetPC() - 1; return mRegisters.GetPC(); } }; typedef WdStackFrame CPUStackFrame; struct WdThreadInfo { public: uint mProcessId; uint mThreadId; HANDLE mHThread; void* mThreadLocalBase; void* mStartAddress; bool mIsBreakRestorePaused; bool mFrozen; addr_target mStartSP; String mName; addr_target mStoppedAtAddress; addr_target mIsAtBreakpointAddress; addr_target mBreakpointAddressContinuing; public: WdThreadInfo() { mProcessId = 0; mThreadId = 0; mHThread = 0; mStartSP = 0; mThreadLocalBase = NULL; mStartAddress = NULL; mIsBreakRestorePaused = false; mFrozen = false; mIsAtBreakpointAddress = 0; mStoppedAtAddress = 0; mBreakpointAddressContinuing = 0; } }; enum DbgTypeKindFlags { DbgTypeKindFlag_None = 0, DbgTypeKindFlag_Int = 1 }; struct DwFormatInfo { int mCallStackIdx; bool mHidePointers; bool mIgnoreDerivedClassInfo; bool mNoVisualizers; bool mNoMembers; bool mRawString; bool mNoEdit; DbgTypeKindFlags mTypeKindFlags; intptr mArrayLength; intptr mOverrideCount; intptr mMaxCount; DwDisplayType mDisplayType; DbgTypedValue mExplicitThis; int mTotalSummaryLength; String mReferenceId; String mSubjectExpr; String mExpectedType; String mNamespaceSearch; int mExpandItemDepth; DbgLanguage mLanguage; DwFormatInfo() { mCallStackIdx = -1; mHidePointers = false; mIgnoreDerivedClassInfo = false; mRawString = false; mNoVisualizers = false; mNoMembers = false; mNoEdit = false; mTypeKindFlags = DbgTypeKindFlag_None; mArrayLength = -1; mOverrideCount = -1; mMaxCount = -1; mTotalSummaryLength = 0; mDisplayType = DwDisplayType_NotSpecified; mExpandItemDepth = 0; mLanguage = DbgLanguage_Unknown; } }; class DbgPendingExpr { public: int mThreadId; BfParser* mParser; DbgType* mExplitType; DwFormatInfo mFormatInfo; DwEvalExpressionFlags mExpressionFlags; int mCursorPos; BfExpression* mExprNode; String mReferenceId; int mCallStackIdx; String mResult; Array mCallResults; int mIdleTicks; String mException; DbgPendingExpr(); ~DbgPendingExpr(); }; class HotTargetMemory { public: addr_target mPtr; int mOffset; int mSize; }; #define WD_MEMCACHE_SIZE 8*1024 struct WdMemoryBreakpointBind { WdBreakpoint* mBreakpoint; addr_target mAddress; int mOfs; int mByteCount; WdMemoryBreakpointBind() { mAddress = 0; mBreakpoint = NULL; mOfs = 0; mByteCount = 0; } }; struct DbgPendingDebugInfoLoad { DbgModule* mModule; bool mAllowRemote; DbgPendingDebugInfoLoad() { mModule = NULL; mAllowRemote = false; } }; struct WinHotThreadState { CPURegisters mRegisters; int mThreadId; }; class WinDbgHeapData { public: struct Stats { intptr mHeapSize; }; public: HANDLE mFileMapping; Stats* mStats; WinDbgHeapData() { mFileMapping = 0; mStats = NULL; } ~WinDbgHeapData() { if (mFileMapping != 0) ::CloseHandle(mFileMapping); } }; class WinDebugger : public Debugger { public: SyncEvent mContinueEvent; Array mHotTargetMemory; Array mHotThreadStates; int mActiveHotIdx; volatile bool mShuttingDown; volatile bool mIsRunning; bool mDestroying; String mLaunchPath; String mTargetPath; String mArgs; String mWorkingDir; Array mEnvBlock; DebugTarget* mEmptyDebugTarget; DebugTarget* mDebugTarget; BfSystem* mBfSystem; CPU* mCPU; PROCESS_INFORMATION mProcessInfo; BfDbgAttachFlags mDbgAttachFlags; WinDbgHeapData* mDbgHeapData; DWORD mDbgProcessId; HANDLE mDbgProcessHandle; HANDLE mDbgThreadHandle; bool mIsDebuggerWaiting; bool mWantsDebugContinue; bool mNeedsRehupBreakpoints; bool mContinueFromBreakpointFailed; WdThreadInfo* mDebuggerWaitingThread; WdThreadInfo* mAtBreakThread; WdThreadInfo* mActiveThread; WdBreakpoint* mActiveBreakpoint; WdThreadInfo* mSteppingThread; WdThreadInfo* mExplicitStopThread; // Don't try to show first frame-with-source for this thread (when we hit breakpoint in asm, encounter exception, etc) DEBUG_EVENT mDebugEvent; bool mGotStartupEvent; int mPageSize; DbgSymSrv mDbgSymSrv; DbgSymRequest* mActiveSymSrvRequest; DWORD mDebuggerThreadId; WdMemoryBreakpointBind mMemoryBreakpoints[4]; Dictionary mPhysBreakpointAddrMap; // To make sure we don't create multiple physical breakpoints at the same addr Array mBreakpoints; Dictionary mBreakpointAddrMap; Array mFreeMemoryBreakIndices; Array mCallStack; bool mIsPartialCallStack; int mRequestedStackFrameIdx; // -1 means to show mShowPCOverride, -2 means "auto" stop, -3 means breakpoint - normally 0 but during inlining the address can be ambiguous int mBreakStackFrameIdx; addr_target mShowPCOverride; Dictionary mThreadMap; Array mThreadList; StepType mOrigStepType; StepType mStepType; int mCurNoInfoStepTries; DbgLineDataEx mStepLineData; bool mStepInAssembly; bool mStepIsRecursing; bool mStepSwitchedThreads; bool mStepStopOnNextInstruction; bool mDbgBreak; addr_target mStepStartPC; addr_target mStepPC; addr_target mStepSP; addr_target mStoredReturnValueAddr; addr_target mLastValidStepIntoPC; bool mIsStepIntoSpecific; CPURegisters mDebugEvalSetRegisters; DbgPendingExpr* mDebugPendingExpr; WdThreadInfo mDebugEvalThreadInfo; // Copy of thread info when eval started Array mPendingImageLoad; Dictionary mPendingDebugInfoLoad; Array mPendingDebugInfoRequests; HashSet mLiteralSet; EXCEPTION_RECORD mCurException; bool mIsContinuingFromException; Array mTempBreakpoint; Array mStepBreakpointAddrs; addr_target mSavedBreakpointAddressContinuing; addr_target mSavedAtBreakpointAddress; BF_CONTEXT mSavedContext; Dictionary mPendingProfilerMap; Array mNewProfilerList; HashSet mProfilerSet; addr_target mMemCacheAddr; uint8 mMemCacheData[WD_MEMCACHE_SIZE]; public: void Fail(const StringImpl& error); void TryGetThreadName(WdThreadInfo* threadInfo); void ThreadRestorePause(WdThreadInfo* onlyPauseThread, WdThreadInfo* dontPauseThread); void ThreadRestoreUnpause(); void UpdateThreadDebugRegisters(WdThreadInfo* threadInfo); void UpdateThreadDebugRegisters(); void ValidateBreakpoints(); void PhysSetBreakpoint(addr_target address); void SetBreakpoint(addr_target address, bool fromRehup = false); void SetTempBreakpoint(addr_target address); void PhysRemoveBreakpoint(addr_target address); void RemoveBreakpoint(addr_target address); void SingleStepX86(); bool IsInRunState(); bool ContinueFromBreakpoint(); bool HasLineInfoAt(addr_target address); DbgLineData* FindLineDataAtAddress(addr_target address, DbgSubprogram** outSubProgram = NULL, DbgSrcFile** outSrcFile = NULL, int* outLineIdx = NULL, DbgOnDemandKind onDemandKind = DbgOnDemandKind_AllowRemote); DbgLineData* FindLineDataInSubprogram(addr_target address, DbgSubprogram* dwSubprogram); bool IsStepFiltered(DbgSubprogram* dbgSubprogram, DbgLineData* dbgLineData); void RemoveTempBreakpoints(); void RehupBreakpoints(bool doFlush); bool WantsBreakpointAt(addr_target address); void CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFile, int lineNum, int hotIdx); void CheckBreakpoint(WdBreakpoint* wdBreakpoint); bool IsMemoryBreakpointSizeValid(addr_target addr, int size); bool HasMemoryBreakpoint(addr_target addr, int size); bool PopulateRegisters(CPURegisters* registers, BF_CONTEXT& lcContext); virtual bool PopulateRegisters(CPURegisters* registers); bool RollBackStackFrame(CPURegisters* registers, bool isStackStart); bool SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget, int newTargetSize); DbgSubprogram* TryFollowHotJump(DbgSubprogram* subprogram, addr_target addr); bool ParseFormatInfo(DbgModule* dbgModule, const StringImpl& formatInfoStr, DwFormatInfo* formatInfo, BfPassInstance* bfPassInstance, int* assignExprOffset, String* assignExpr = NULL, String* errorString = NULL, DbgTypedValue contextTypedValue = DbgTypedValue()); String MaybeQuoteFormatInfoParam(const StringImpl& str); void DbgVisFailed(DebugVisualizerEntry* debugVis, const StringImpl& evalString, const StringImpl& errors); DbgTypedValue EvaluateInContext(DbgCompileUnit* dbgCompileUnit, const DbgTypedValue& contextTypedValue, const StringImpl& subExpr, DwFormatInfo* formatInfo = NULL, String* outReferenceId = NULL, String* outErrors = NULL); bool EvalCondition(DebugVisualizerEntry* debugVis, DbgCompileUnit* dbgCompileUnit, DbgTypedValue typedVal, DwFormatInfo& formatInfo, const StringImpl& condition, const Array& dbgVisWildcardCaptures, String& errorStr); DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId); void ProcessEvalString(DbgCompileUnit* dbgCompileUnit, DbgTypedValue useTypedValue, String& evalStr, String& displayString, DwFormatInfo& formatInfo, DebugVisualizerEntry* debugVis, bool limitLength); String ReadString(DbgTypeCode charType, intptr addr, bool isLocalAddr, intptr maxLength, DwFormatInfo& formatInfo); String DbgTypedValueToString(const DbgTypedValue& typedValue, const StringImpl& expr, DwFormatInfo& formatFlags, DbgExprEvaluator* optEvaluator, bool fullPrecision = false); bool ShouldShowStaticMember(DbgType* dbgType, DbgVariable* member); String GetMemberList(DbgType* dbgType, const StringImpl& expr, bool isPtr, bool isStatic, bool forceCast = false, bool isSplat = false, bool isReadOnly = false); DebugVisualizerEntry* FindVisualizerForType(DbgType* dbgType, Array* wildcardCaptures); void ReserveHotTargetMemory(int size); addr_target AllocHotTargetMemory(int size, bool canExecute, bool canWrite, int* outAllocSize); void ReleaseHotTargetMemory(addr_target addr, int size); void CleanupHotHeap(); int EnableWriting(intptr address, int size); int SetProtection(intptr address, int size, int prot); void EnableMemCache(); void DisableMemCache(); template T ReadMemory(intptr addr, bool local = false, bool* failed = NULL); bool WriteInstructions(intptr address, void* src, uint64 length); template bool WriteMemory(intptr addr, T val); virtual DbgMemoryFlags GetMemoryFlags(intptr address) override; void SetRunState(RunState runState); bool IsPaused(); void ClearStep(); bool SetupStep(StepType stepType); void CheckNonDebuggerBreak(); bool HasSteppedIntoCall(); void StepLineTryPause(addr_target address, bool requireExactMatch); void PushValue(CPURegisters* registers, int64 val); void PushValue(CPURegisters* registers, const DbgTypedValue& typedValue); void SetThisRegister(CPURegisters* registers, addr_target val); void AddParamValue(int paramIdx, bool hadThis, CPURegisters* registers, const DbgTypedValue& typedValue); bool CheckNeedsSRetArgument(DbgType* retType); DbgTypedValue ReadReturnValue(CPURegisters* registers, DbgType* type); bool SetRegisters(CPURegisters* registers); void SaveAllRegisters(); void RestoreAllRegisters(); String GetArrayItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData); String GetLinkedListItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, addr_target endNodePtr, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData); String GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgTypedValue dictValue, int bucketIdx, int nodeIdx, int& count, String* outContinuationData); String GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, Array& parentList, DbgType*& valueType, DbgTypedValue& curNode, int count, String* outContinuationData); void HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgType* dwUseType, DbgType* dwValueType, String& ptrUseDataStr, String& ptrDataStr, DbgTypedValue useTypedValue, Array& dbgVisWildcardCaptures, DwFormatInfo& formatInfo); void ModuleChanged(DbgModule* dbgModule); bool DoUpdate(); void DebugThreadProc(); bool DoOpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array& envBlock); DbgTypedValue GetRegister(const StringImpl& regName, DbgLanguage language, CPURegisters* registers, Array* regForms = NULL); void FixupLineData(DbgCompileUnit* compileUnit); void FixupLineDataForSubprogram(DbgSubprogram* subProgram); DbgModule* GetCallStackDbgModule(int callStackIdx); DbgSubprogram* GetCallStackSubprogram(int callStackIdx); DbgCompileUnit* GetCallStackCompileUnit(int callStackIdx); String Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags); String EvaluateContinue() override; void EvaluateContinueKeep() override; String EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance& bfPassInstance); String GetAutocompleteOutput(DwAutoComplete& autoComplete); bool CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubprogram* dbgSubprogram, addr_target pcAddress); void CleanupDebugEval(bool restoreRegisters = true); bool FixCallStackIdx(int& callStackIdx); int LoadDebugInfoForModule(DbgModule* dbgModule); public: WinDebugger(DebugManager* debugManager); virtual ~WinDebugger(); virtual void OutputMessage(const StringImpl& msg) override; virtual void OutputRawMessage(const StringImpl& msg) override; virtual int GetAddrSize() override; virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) override; virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array& envBlock) override; virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override; virtual void Run() override; virtual void HotLoad(const Array& objectFiles, int hotIdx) override; virtual void InitiateHotResolve(DbgHotResolveFlags flags) override; virtual intptr GetDbgAllocHeapSize() override; virtual String GetDbgAllocInfo() override; virtual void Update() override; virtual void ContinueDebugEvent() override; virtual void ForegroundTarget() override; virtual Breakpoint* CreateBreakpoint(const StringImpl& fileName, int lineNum, int wantColumn, int instrOffset) override; virtual Breakpoint* CreateMemoryBreakpoint(intptr addr, int byteCount) override; virtual Breakpoint* CreateSymbolBreakpoint(const StringImpl& symbolName) override; virtual Breakpoint* CreateAddressBreakpoint(intptr address) override; virtual void CheckBreakpoint(Breakpoint* breakpoint) override; virtual void HotBindBreakpoint(Breakpoint* breakpoint, int lineNum, int hotIdx) override; virtual void DeleteBreakpoint(Breakpoint* breakpoint) override; virtual void DetachBreakpoint(Breakpoint* breakpoint) override; virtual void MoveBreakpoint(Breakpoint* breakpoint, int lineNum, int wantColumn, bool rebindNow) override; virtual void MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int byteCount) override; virtual void DisableBreakpoint(Breakpoint* breakpoint) override; virtual void SetBreakpointCondition(Breakpoint* breakpoint, const StringImpl& condition) override; virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) override; virtual Breakpoint* FindBreakpointAt(intptr address) override; virtual Breakpoint* GetActiveBreakpoint() override; virtual void BreakAll() override; virtual bool TryRunContinue() override; virtual void StepInto(bool inAssembly) override; virtual void StepIntoSpecific(intptr addr) override; virtual void StepOver(bool inAssembly) override; virtual void StepOut(bool inAssembly) override; virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) override; virtual String Evaluate(const StringImpl& expr, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) override; virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) override; virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) override; virtual bool AssignToReg(int callStackIdx, DbgTypedValue reg, DbgTypedValue value, String& outError); virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) override; virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) override; virtual String GetAutoLocals(int callStackIdx, bool showRegs) override; virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) override; virtual String GetProcessInfo() override; virtual String GetThreadInfo() override; virtual void SetActiveThread(int threadId) override; virtual int GetActiveThread() override; virtual void FreezeThread(int threadId) override; virtual void ThawThread(int threadId) override; virtual bool IsActiveThreadWaiting() override; virtual void ClearCallStack() override; virtual void UpdateCallStack(bool slowEarlyOut = true) override; virtual int GetCallStackCount() override; virtual int GetRequestedStackFrameIdx() override; virtual int GetBreakStackFrameIdx() override; virtual bool ReadMemory(intptr address, uint64 length, void* dest, bool local = false) override; virtual bool WriteMemory(intptr address, void* src, uint64 length) override; addr_target GetTLSOffset(int tlsIndex); virtual void UpdateRegisterUsage(int stackFrameIdx) override; virtual void UpdateCallStackMethod(int stackFrameIdx) override; virtual void GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override; virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) override; virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn, int* outLanguage, int* outStackSize, int8* outFlags) override; virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) override; virtual int GetJmpState(int stackFrameIdx) override; virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) override; virtual String GetStackMethodOwner(int stackFrameIdx, int& language) override; virtual String FindCodeAddresses(const StringImpl& fileName, int line, int column, bool allowAutoResolve) override; virtual String GetAddressSourceLocation(intptr address) override; virtual String GetAddressSymbolName(intptr address, bool demangle) override; virtual String DisassembleAtRaw(intptr address) override; virtual String DisassembleAt(intptr address) override; virtual String FindLineCallAddresses(intptr address) override; virtual String GetCurrentException() override; virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) override; virtual String GetModulesInfo() override; virtual void CancelSymSrv() override; virtual bool HasPendingDebugLoads() override; virtual int LoadImageForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override; virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override; virtual int LoadDebugInfoForModule(const StringImpl& moduleName) override; virtual void StopDebugging() override; virtual void Terminate() override; virtual void Detach() override; virtual Profiler* StartProfiling() override; virtual Profiler* PopProfiler() override; void AddProfiler(DbgProfiler* profiler); void RemoveProfiler(DbgProfiler* profiler); virtual void ReportMemory(MemReporter* memReporter) override; virtual bool IsOnDemandDebugger() override { return false; } virtual bool IsMiniDumpDebugger() { return false; } }; template bool WinDebugger::WriteMemory(intptr addr, T val) { SIZE_T dwWriteBytes; return WriteProcessMemory(mProcessInfo.hProcess, (void*)(intptr)addr, &val, (SIZE_T)sizeof(T), &dwWriteBytes) != 0; } template T WinDebugger::ReadMemory(intptr addr, bool local, bool* failed) { bool success = true; T val; memset(&val, 0, sizeof(T)); if (local) { if (addr != 0) { memcpy(&val, (void*)(intptr)addr, sizeof(T)); /*__try { memcpy(&val, (void*)(intptr)addr, sizeof(T)); } __except (EXCEPTION_EXECUTE_HANDLER) { success = false; }*/ } else success = false; } else { //SIZE_T dwReadBytes; memset(&val, 0, sizeof(T)); //success = ReadProcessMemory(mProcessInfo.hProcess, (void*)(intptr)addr, &val, (SIZE_T)sizeof(T), &dwReadBytes) != 0; success = ReadMemory(addr, (int)sizeof(T), &val); } if (failed != NULL) *failed = !success; return val; } addr_target DecodeTargetDataPtr(const char*& strRef); NS_BF_DBG_END