2019-08-23 11:56:54 -07:00
# 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
2020-04-16 10:46:58 -07:00
class DbgProfiler ;
2019-08-23 11:56:54 -07:00
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 < RegForm > 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 ;
}
} ;
2019-12-24 10:31:38 -08:00
enum DbgTypeKindFlags
{
DbgTypeKindFlag_None = 0 ,
DbgTypeKindFlag_Int = 1
} ;
2019-08-23 11:56:54 -07:00
struct DwFormatInfo
{
int mCallStackIdx ;
bool mHidePointers ;
bool mIgnoreDerivedClassInfo ;
bool mNoVisualizers ;
bool mNoMembers ;
bool mRawString ;
bool mNoEdit ;
2019-12-24 10:31:38 -08:00
DbgTypeKindFlags mTypeKindFlags ;
2019-12-09 10:29:31 -08:00
intptr mArrayLength ;
intptr mOverrideCount ;
intptr mMaxCount ;
2019-08-23 11:56:54 -07:00
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 ;
2019-12-24 10:31:38 -08:00
mTypeKindFlags = DbgTypeKindFlag_None ;
2019-08-23 11:56:54 -07:00
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 < DbgCallResult > 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 ;
}
} ;
2019-09-20 09:21:29 -07:00
struct DbgPendingDebugInfoLoad
{
DbgModule * mModule ;
bool mAllowRemote ;
DbgPendingDebugInfoLoad ( )
{
mModule = NULL ;
mAllowRemote = false ;
}
} ;
2020-06-15 14:48:25 -07:00
struct WinHotThreadState
{
CPURegisters mRegisters ;
int mThreadId ;
} ;
2020-07-31 06:16:29 -07:00
class WinDbgHeapData
{
public :
struct Stats
{
intptr mHeapSize ;
} ;
public :
HANDLE mFileMapping ;
Stats * mStats ;
WinDbgHeapData ( )
{
mFileMapping = 0 ;
mStats = NULL ;
}
~ WinDbgHeapData ( )
{
if ( mFileMapping ! = 0 )
: : CloseHandle ( mFileMapping ) ;
}
} ;
2019-08-23 11:56:54 -07:00
class WinDebugger : public Debugger
{
public :
SyncEvent mContinueEvent ;
Array < HotTargetMemory > mHotTargetMemory ;
2020-06-15 14:48:25 -07:00
Array < WinHotThreadState > mHotThreadStates ;
2019-08-23 11:56:54 -07:00
int mActiveHotIdx ;
volatile bool mShuttingDown ;
volatile bool mIsRunning ;
bool mDestroying ;
2019-09-02 17:39:47 -07:00
String mLaunchPath ;
String mTargetPath ;
2019-08-23 11:56:54 -07:00
String mArgs ;
String mWorkingDir ;
Array < uint8 > mEnvBlock ;
DebugTarget * mEmptyDebugTarget ;
DebugTarget * mDebugTarget ;
BfSystem * mBfSystem ;
CPU * mCPU ;
PROCESS_INFORMATION mProcessInfo ;
BfDbgAttachFlags mDbgAttachFlags ;
2020-07-31 06:16:29 -07:00
WinDbgHeapData * mDbgHeapData ;
2019-08-23 11:56:54 -07:00
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 ] ;
2020-03-14 16:15:38 -07:00
Dictionary < addr_target , int > mPhysBreakpointAddrMap ; // To make sure we don't create multiple physical breakpoints at the same addr
Array < WdBreakpoint * > mBreakpoints ;
Dictionary < addr_target , WdBreakpoint * > mBreakpointAddrMap ;
2019-08-23 11:56:54 -07:00
Array < int > mFreeMemoryBreakIndices ;
Array < WdStackFrame * > 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 < uint32 , WdThreadInfo * > mThreadMap ;
Array < WdThreadInfo * > 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 < DbgModule * > mPendingImageLoad ;
2019-09-20 09:21:29 -07:00
Dictionary < DbgModule * , DbgPendingDebugInfoLoad > mPendingDebugInfoLoad ;
2019-08-23 11:56:54 -07:00
Array < DbgModule * > mPendingDebugInfoRequests ;
HashSet < String > mLiteralSet ;
EXCEPTION_RECORD mCurException ;
bool mIsContinuingFromException ;
Array < int64 > mTempBreakpoint ;
Array < int64 > mStepBreakpointAddrs ;
addr_target mSavedBreakpointAddressContinuing ;
addr_target mSavedAtBreakpointAddress ;
BF_CONTEXT mSavedContext ;
Dictionary < int , Profiler * > mPendingProfilerMap ;
Array < Profiler * > mNewProfilerList ;
2020-04-16 10:46:58 -07:00
HashSet < Profiler * > mProfilerSet ;
2019-08-23 11:56:54 -07:00
addr_target mMemCacheAddr ;
uint8 mMemCacheData [ WD_MEMCACHE_SIZE ] ;
public :
2019-09-02 17:39:47 -07:00
void Fail ( const StringImpl & error ) ;
2019-08-23 11:56:54 -07:00
void TryGetThreadName ( WdThreadInfo * threadInfo ) ;
void ThreadRestorePause ( WdThreadInfo * onlyPauseThread , WdThreadInfo * dontPauseThread ) ;
void ThreadRestoreUnpause ( ) ;
void UpdateThreadDebugRegisters ( WdThreadInfo * threadInfo ) ;
void UpdateThreadDebugRegisters ( ) ;
2020-03-14 16:15:38 -07:00
void ValidateBreakpoints ( ) ;
2019-08-23 11:56:54 -07:00
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 ) ;
2019-09-03 11:17:13 -07:00
bool SetHotJump ( DbgSubprogram * oldSubprogram , addr_target newTarget , int newTargetSize ) ;
2019-09-02 17:39:47 -07:00
DbgSubprogram * TryFollowHotJump ( DbgSubprogram * subprogram , addr_target addr ) ;
2019-08-23 11:56:54 -07:00
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 < String > & dbgVisWildcardCaptures , String & errorStr ) ;
DwDisplayInfo * GetDisplayInfo ( const StringImpl & referenceId ) ;
void ProcessEvalString ( DbgCompileUnit * dbgCompileUnit , DbgTypedValue useTypedValue , String & evalStr , String & displayString , DwFormatInfo & formatInfo , DebugVisualizerEntry * debugVis , bool limitLength ) ;
2019-12-09 10:29:31 -08:00
String ReadString ( DbgTypeCode charType , intptr addr , bool isLocalAddr , intptr maxLength , DwFormatInfo & formatInfo ) ;
2019-08-23 11:56:54 -07:00
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 < String > * 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 < typename T > T ReadMemory ( intptr addr , bool local = false , bool * failed = NULL ) ;
bool WriteInstructions ( intptr address , void * src , uint64 length ) ;
template < typename T > 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 < addr_target > & 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 < String > & dbgVisWildcardCaptures , DwFormatInfo & formatInfo ) ;
void ModuleChanged ( DbgModule * dbgModule ) ;
bool DoUpdate ( ) ;
void DebugThreadProc ( ) ;
bool DoOpenFile ( const StringImpl & fileName , const StringImpl & args , const StringImpl & workingDir , const Array < uint8 > & envBlock ) ;
DbgTypedValue GetRegister ( const StringImpl & regName , DbgLanguage language , CPURegisters * registers , Array < RegForm > * 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 ) ;
2019-09-27 13:05:39 -07:00
bool FixCallStackIdx ( int & callStackIdx ) ;
int LoadDebugInfoForModule ( DbgModule * dbgModule ) ;
2019-08-23 11:56:54 -07:00
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 ;
2019-09-02 17:39:47 -07:00
virtual void OpenFile ( const StringImpl & launchPath , const StringImpl & targetPath , const StringImpl & args , const StringImpl & workingDir , const Array < uint8 > & envBlock ) override ;
2019-08-23 11:56:54 -07:00
virtual bool Attach ( int processId , BfDbgAttachFlags attachFlags ) override ;
virtual void Run ( ) override ;
virtual void HotLoad ( const Array < String > & objectFiles , int hotIdx ) override ;
virtual void InitiateHotResolve ( DbgHotResolveFlags flags ) override ;
2020-07-31 06:16:29 -07:00
virtual intptr GetDbgAllocHeapSize ( ) override ;
virtual String GetDbgAllocInfo ( ) override ;
2019-08-23 11:56:54 -07:00
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 ;
2020-03-14 16:15:38 -07:00
virtual void SetBreakpointLogging ( Breakpoint * wdBreakpoint , const StringImpl & logging , bool breakAfterLogging ) override ;
2019-08-23 11:56:54 -07:00
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 ;
2020-07-18 06:50:28 -07:00
virtual String GetProcessInfo ( ) override ;
2019-08-23 11:56:54 -07:00
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 ;
2019-09-27 13:05:39 -07:00
virtual int LoadImageForModule ( const StringImpl & moduleName , const StringImpl & debugFileName ) override ;
virtual int LoadDebugInfoForModule ( const StringImpl & moduleName , const StringImpl & debugFileName ) override ;
2019-08-23 11:56:54 -07:00
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 ;
2020-04-16 10:46:58 -07:00
void AddProfiler ( DbgProfiler * profiler ) ;
void RemoveProfiler ( DbgProfiler * profiler ) ;
virtual void ReportMemory ( MemReporter * memReporter ) override ;
2019-08-23 11:56:54 -07:00
virtual bool IsOnDemandDebugger ( ) override { return false ; }
virtual bool IsMiniDumpDebugger ( ) { return false ; }
} ;
template < typename T > 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 < typename T > 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