WinDebugger.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. #pragma once
  2. #include "BeefySysLib/Common.h"
  3. #include "BeefySysLib/Util/PerfTimer.h"
  4. #include "DbgSymSrv.h"
  5. #include "DebugTarget.h"
  6. #include "DbgExprEvaluator.h"
  7. #include "Debugger.h"
  8. #include "HotHeap.h"
  9. #include "COFF.h"
  10. namespace Beefy
  11. {
  12. class BfSystem;
  13. class BfReducer;
  14. class BfPassInstance;
  15. class DebugManager;
  16. class DebugVisualizers;
  17. class DebugVisualizerEntry;
  18. };
  19. NS_BF_DBG_BEGIN
  20. class DbgModule;
  21. class DbgSrcFile;
  22. class DbgLineData;
  23. class X86;
  24. class HotHeap;
  25. #ifdef BF_DBG_32
  26. #ifdef BF32
  27. #define BF_CONTEXT CONTEXT
  28. #define BF_GetThreadContext GetThreadContext
  29. #define BF_SetThreadContext SetThreadContext
  30. #define BF_CONTEXT_CONTROL CONTEXT_CONTROL
  31. #define BF_CONTEXT_INTEGER CONTEXT_INTEGER
  32. #define BF_CONTEXT_SEGMENTS CONTEXT_SEGMENTS
  33. #define BF_CONTEXT_FLOATING_POINT CONTEXT_FLOATING_POINT
  34. #define BF_CONTEXT_DEBUG_REGISTERS CONTEXT_DEBUG_REGISTERS
  35. #define BF_CONTEXT_EXTENDED_REGISTERS CONTEXT_EXTENDED_REGISTERS
  36. #define BF_CONTEXT_EXCEPTION_REQUEST CONTEXT_EXCEPTION_REQUEST
  37. #define BF_CONTEXT_EXCEPTION_ACTIVE CONTEXT_EXCEPTION_ACTIVE
  38. #define BF_CONTEXT_SERVICE_ACTIVE CONTEXT_SERVICE_ACTIVE
  39. #define BF_CONTEXT_ALL CONTEXT_ALL
  40. #define BF_CONTEXT_SP(ctx) ctx.Esp
  41. #define BF_CONTEXT_BP(ctx) ctx.Ebp
  42. #define BF_CONTEXT_IP(ctx) ctx.Eip
  43. #define BF_CONTEXT_FLTDATA(ctx) ctx.FloatSave.RegisterArea
  44. #define BF_CONTEXT_XMMDATA(ctx) &ctx.ExtendedRegisters[160]
  45. #else
  46. #define BF_CONTEXT WOW64_CONTEXT
  47. #define BF_GetThreadContext Wow64GetThreadContext
  48. #define BF_SetThreadContext Wow64SetThreadContext
  49. #define BF_CONTEXT_CONTROL WOW64_CONTEXT_CONTROL
  50. #define BF_CONTEXT_INTEGER WOW64_CONTEXT_INTEGER
  51. #define BF_CONTEXT_SEGMENTS WOW64_CONTEXT_SEGMENTS
  52. #define BF_CONTEXT_FLOATING_POINT WOW64_CONTEXT_FLOATING_POINT
  53. #define BF_CONTEXT_DEBUG_REGISTERS WOW64_CONTEXT_DEBUG_REGISTERS
  54. #define BF_CONTEXT_EXTENDED_REGISTERS WOW64_CONTEXT_EXTENDED_REGISTERS
  55. #define BF_CONTEXT_EXCEPTION_REQUEST WOW64_CONTEXT_EXCEPTION_REQUEST
  56. #define BF_CONTEXT_EXCEPTION_ACTIVE WOW64_CONTEXT_EXCEPTION_ACTIVE
  57. #define BF_CONTEXT_SERVICE_ACTIVE WOW64_CONTEXT_SERVICE_ACTIVE
  58. #define BF_CONTEXT_ALL WOW64_CONTEXT_ALL
  59. #define BF_CONTEXT_SP(ctx) ctx.Esp
  60. #define BF_CONTEXT_BP(ctx) ctx.Ebp
  61. #define BF_CONTEXT_IP(ctx) ctx.Eip
  62. #define BF_CONTEXT_FLTDATA(ctx) ctx.FloatSave.RegisterArea
  63. #define BF_CONTEXT_XMMDATA(ctx) &ctx.ExtendedRegisters[160]
  64. #endif
  65. #else // BG_DBG_64
  66. #define BF_CONTEXT CONTEXT
  67. #define BF_GetThreadContext GetThreadContext
  68. #define BF_SetThreadContext SetThreadContext
  69. #define BF_CONTEXT_CONTROL CONTEXT_CONTROL
  70. #define BF_CONTEXT_INTEGER CONTEXT_INTEGER
  71. #define BF_CONTEXT_SEGMENTS CONTEXT_SEGMENTS
  72. #define BF_CONTEXT_FLOATING_POINT CONTEXT_FLOATING_POINT
  73. #define BF_CONTEXT_DEBUG_REGISTERS CONTEXT_DEBUG_REGISTERS
  74. #define BF_CONTEXT_EXTENDED_REGISTERS 0
  75. #define BF_CONTEXT_EXCEPTION_REQUEST CONTEXT_EXCEPTION_REQUEST
  76. #define BF_CONTEXT_EXCEPTION_ACTIVE CONTEXT_EXCEPTION_ACTIVE
  77. #define BF_CONTEXT_SERVICE_ACTIVE CONTEXT_SERVICE_ACTIVE
  78. #define BF_CONTEXT_ALL CONTEXT_ALL
  79. #define BF_CONTEXT_SP(ctx) ctx.Rsp
  80. #define BF_CONTEXT_BP(ctx) ctx.Rbp
  81. #define BF_CONTEXT_IP(ctx) ctx.Rip
  82. #define BF_CONTEXT_FLTDATA(ctx) ctx.FltSave.FloatRegisters
  83. #define BF_CONTEXT_XMMDATA(ctx) ctx.FltSave.XmmRegisters
  84. #endif
  85. enum BreakpointType
  86. {
  87. BreakpointType_User,
  88. BreakpointType_Stepping
  89. };
  90. struct DwFormatInfo;
  91. class DbgEvaluationContext
  92. {
  93. public:
  94. BfParser* mParser;
  95. BfReducer* mReducer;
  96. BfPassInstance* mPassInstance;
  97. DbgExprEvaluator* mDbgExprEvaluator;
  98. BfExpression* mExprNode;
  99. public:
  100. DbgEvaluationContext(WinDebugger* winDebugger, DbgModule* dbgModule, const StringImpl& expr, DwFormatInfo* formatInfo = NULL, DbgTypedValue contextValue = DbgTypedValue());
  101. DbgEvaluationContext(WinDebugger* winDebugger, DbgCompileUnit* dbgCompileUnit, const StringImpl& expr, DwFormatInfo* formatInfo = NULL, DbgTypedValue contextValue = DbgTypedValue());
  102. void Init(WinDebugger* winDebugger, DbgModule* dbgModule, const StringImpl& expr, DwFormatInfo* formatInfo = NULL, DbgTypedValue contextValue = DbgTypedValue());
  103. bool HasExpression();
  104. ~DbgEvaluationContext();
  105. DbgTypedValue EvaluateInContext(DbgTypedValue contextTypedValue);
  106. String GetErrorStr();
  107. bool HadError();
  108. };
  109. class WdBreakpointCondition
  110. {
  111. public:
  112. DbgEvaluationContext* mDbgEvaluationContext;
  113. String mExpr;
  114. ~WdBreakpointCondition();
  115. };
  116. class WdMemoryBreakpointInfo
  117. {
  118. public:
  119. addr_target mMemoryAddress;
  120. int mByteCount;
  121. String mReferenceName;
  122. int8 mMemoryWatchSlotBitmap;
  123. WdMemoryBreakpointInfo()
  124. {
  125. mMemoryAddress = 0;
  126. mByteCount = 0;
  127. mMemoryWatchSlotBitmap = 0;
  128. }
  129. };
  130. class WdBreakpoint : public Breakpoint
  131. {
  132. public:
  133. WdMemoryBreakpointInfo* mMemoryBreakpointInfo;
  134. addr_target mAddr;
  135. DbgSrcFile* mSrcFile;
  136. DbgLineDataEx mLineData;
  137. WdBreakpointCondition* mCondition;
  138. BreakpointType mBreakpointType;
  139. public:
  140. WdBreakpoint()
  141. {
  142. mMemoryBreakpointInfo = NULL;
  143. mAddr = 0;
  144. mSrcFile = NULL;
  145. mLineData = DbgLineDataEx();
  146. mCondition = NULL;
  147. mBreakpointType = BreakpointType_User;
  148. }
  149. virtual uintptr GetAddr() override
  150. {
  151. return (uintptr)mAddr;
  152. }
  153. virtual bool IsMemoryBreakpointBound() override
  154. {
  155. return (mMemoryBreakpointInfo != NULL) && (mMemoryBreakpointInfo->mMemoryWatchSlotBitmap != 0);
  156. }
  157. WdBreakpoint* GetHeadBreakpoint()
  158. {
  159. if (mHead != NULL)
  160. return (WdBreakpoint*)mHead;
  161. return this;
  162. }
  163. };
  164. enum StepType
  165. {
  166. StepType_None,
  167. StepType_StepInto,
  168. StepType_StepInto_Unfiltered,
  169. StepType_StepInto_UnfilteredSingle,
  170. StepType_StepOver,
  171. StepType_StepOut,
  172. StepType_StepOut_ThenInto, // For supporting step filters
  173. StepType_StepOut_NoFrame,
  174. StepType_StepOut_Inline,
  175. StepType_ToTempBreakpoint
  176. };
  177. class WdStackFrame
  178. {
  179. public:
  180. CPURegisters mRegisters;
  181. bool mIsStart;
  182. bool mIsEnd;
  183. bool mInInlineMethod;
  184. bool mInInlineCall; // Means the frame above us is inlined
  185. DbgSubprogram* mSubProgram;
  186. bool mHasGottenSubProgram;
  187. Array<RegForm> mRegForms;
  188. public:
  189. WdStackFrame()
  190. {
  191. mSubProgram = NULL;
  192. mHasGottenSubProgram = false;
  193. mIsStart = true;
  194. mIsEnd = false;
  195. mInInlineMethod = false;
  196. mInInlineCall = false;
  197. }
  198. addr_target GetSourcePC()
  199. {
  200. // 'PC' is return address of call in these cases, so subtract 1 for cases where
  201. // we want to bring it back into the calling block range (note that this doesn't
  202. // properly determine the actual starting address of the call instruction, though)
  203. if ((!mIsStart) && (!mInInlineCall))
  204. return mRegisters.GetPC() - 1;
  205. return mRegisters.GetPC();
  206. }
  207. };
  208. typedef WdStackFrame CPUStackFrame;
  209. struct WdThreadInfo
  210. {
  211. public:
  212. uint mProcessId;
  213. uint mThreadId;
  214. HANDLE mHThread;
  215. void* mThreadLocalBase;
  216. void* mStartAddress;
  217. bool mIsBreakRestorePaused;
  218. bool mFrozen;
  219. addr_target mStartSP;
  220. String mName;
  221. addr_target mStoppedAtAddress;
  222. addr_target mIsAtBreakpointAddress;
  223. addr_target mBreakpointAddressContinuing;
  224. public:
  225. WdThreadInfo()
  226. {
  227. mProcessId = 0;
  228. mThreadId = 0;
  229. mHThread = 0;
  230. mStartSP = 0;
  231. mThreadLocalBase = NULL;
  232. mStartAddress = NULL;
  233. mIsBreakRestorePaused = false;
  234. mFrozen = false;
  235. mIsAtBreakpointAddress = 0;
  236. mStoppedAtAddress = 0;
  237. mBreakpointAddressContinuing = 0;
  238. }
  239. };
  240. struct DwFormatInfo
  241. {
  242. int mCallStackIdx;
  243. bool mHidePointers;
  244. bool mIgnoreDerivedClassInfo;
  245. bool mNoVisualizers;
  246. bool mNoMembers;
  247. bool mRawString;
  248. bool mNoEdit;
  249. int mArrayLength;
  250. int mOverrideCount;
  251. int mMaxCount;
  252. DwDisplayType mDisplayType;
  253. DbgTypedValue mExplicitThis;
  254. int mTotalSummaryLength;
  255. String mReferenceId;
  256. String mSubjectExpr;
  257. String mExpectedType;
  258. String mNamespaceSearch;
  259. int mExpandItemDepth;
  260. DbgLanguage mLanguage;
  261. DwFormatInfo()
  262. {
  263. mCallStackIdx = -1;
  264. mHidePointers = false;
  265. mIgnoreDerivedClassInfo = false;
  266. mRawString = false;
  267. mNoVisualizers = false;
  268. mNoMembers = false;
  269. mNoEdit = false;
  270. mArrayLength = -1;
  271. mOverrideCount = -1;
  272. mMaxCount = -1;
  273. mTotalSummaryLength = 0;
  274. mDisplayType = DwDisplayType_NotSpecified;
  275. mExpandItemDepth = 0;
  276. mLanguage = DbgLanguage_Unknown;
  277. }
  278. };
  279. class DbgPendingExpr
  280. {
  281. public:
  282. int mThreadId;
  283. BfParser* mParser;
  284. DbgType* mExplitType;
  285. DwFormatInfo mFormatInfo;
  286. DwEvalExpressionFlags mExpressionFlags;
  287. int mCursorPos;
  288. BfExpression* mExprNode;
  289. String mReferenceId;
  290. int mCallStackIdx;
  291. String mResult;
  292. Array<DbgCallResult> mCallResults;
  293. int mIdleTicks;
  294. String mException;
  295. DbgPendingExpr();
  296. ~DbgPendingExpr();
  297. };
  298. class HotTargetMemory
  299. {
  300. public:
  301. addr_target mPtr;
  302. int mOffset;
  303. int mSize;
  304. };
  305. #define WD_MEMCACHE_SIZE 8*1024
  306. struct WdMemoryBreakpointBind
  307. {
  308. WdBreakpoint* mBreakpoint;
  309. addr_target mAddress;
  310. int mOfs;
  311. int mByteCount;
  312. WdMemoryBreakpointBind()
  313. {
  314. mAddress = 0;
  315. mBreakpoint = NULL;
  316. mOfs = 0;
  317. mByteCount = 0;
  318. }
  319. };
  320. struct DbgPendingDebugInfoLoad
  321. {
  322. DbgModule* mModule;
  323. bool mAllowRemote;
  324. DbgPendingDebugInfoLoad()
  325. {
  326. mModule = NULL;
  327. mAllowRemote = false;
  328. }
  329. };
  330. class WinDebugger : public Debugger
  331. {
  332. public:
  333. SyncEvent mContinueEvent;
  334. Array<HotTargetMemory> mHotTargetMemory;
  335. Array<CPURegisters> mHotThreadStates;
  336. int mActiveHotIdx;
  337. volatile bool mShuttingDown;
  338. volatile bool mIsRunning;
  339. bool mDestroying;
  340. String mLaunchPath;
  341. String mTargetPath;
  342. String mArgs;
  343. String mWorkingDir;
  344. Array<uint8> mEnvBlock;
  345. DebugTarget* mEmptyDebugTarget;
  346. DebugTarget* mDebugTarget;
  347. BfSystem* mBfSystem;
  348. CPU* mCPU;
  349. PROCESS_INFORMATION mProcessInfo;
  350. BfDbgAttachFlags mDbgAttachFlags;
  351. DWORD mDbgProcessId;
  352. HANDLE mDbgProcessHandle;
  353. HANDLE mDbgThreadHandle;
  354. bool mIsDebuggerWaiting;
  355. bool mWantsDebugContinue;
  356. bool mNeedsRehupBreakpoints;
  357. bool mContinueFromBreakpointFailed;
  358. WdThreadInfo* mDebuggerWaitingThread;
  359. WdThreadInfo* mAtBreakThread;
  360. WdThreadInfo* mActiveThread;
  361. WdBreakpoint* mActiveBreakpoint;
  362. WdThreadInfo* mSteppingThread;
  363. WdThreadInfo* mExplicitStopThread; // Don't try to show first frame-with-source for this thread (when we hit breakpoint in asm, encounter exception, etc)
  364. DEBUG_EVENT mDebugEvent;
  365. bool mGotStartupEvent;
  366. int mPageSize;
  367. DbgSymSrv mDbgSymSrv;
  368. DbgSymRequest* mActiveSymSrvRequest;
  369. DWORD mDebuggerThreadId;
  370. WdMemoryBreakpointBind mMemoryBreakpoints[4];
  371. Dictionary<addr_target, int> mBreakpointAddrMap; // To make sure we don't create multiple physical breakpoints at the same addr
  372. Array<WdBreakpoint*> mBreakpoints;
  373. Array<int> mFreeMemoryBreakIndices;
  374. Array<WdStackFrame*> mCallStack;
  375. bool mIsPartialCallStack;
  376. int mRequestedStackFrameIdx; // -1 means to show mShowPCOverride, -2 means "auto" stop, -3 means breakpoint - normally 0 but during inlining the address can be ambiguous
  377. int mBreakStackFrameIdx;
  378. addr_target mShowPCOverride;
  379. Dictionary<uint32, WdThreadInfo*> mThreadMap;
  380. Array<WdThreadInfo*> mThreadList;
  381. StepType mOrigStepType;
  382. StepType mStepType;
  383. int mCurNoInfoStepTries;
  384. DbgLineDataEx mStepLineData;
  385. bool mStepInAssembly;
  386. bool mStepIsRecursing;
  387. bool mStepSwitchedThreads;
  388. bool mStepStopOnNextInstruction;
  389. bool mDbgBreak;
  390. addr_target mStepStartPC;
  391. addr_target mStepPC;
  392. addr_target mStepSP;
  393. addr_target mStoredReturnValueAddr;
  394. addr_target mLastValidStepIntoPC;
  395. bool mIsStepIntoSpecific;
  396. CPURegisters mDebugEvalSetRegisters;
  397. DbgPendingExpr* mDebugPendingExpr;
  398. WdThreadInfo mDebugEvalThreadInfo; // Copy of thread info when eval started
  399. Array<DbgModule*> mPendingImageLoad;
  400. Dictionary<DbgModule*, DbgPendingDebugInfoLoad> mPendingDebugInfoLoad;
  401. Array<DbgModule*> mPendingDebugInfoRequests;
  402. HashSet<String> mLiteralSet;
  403. EXCEPTION_RECORD mCurException;
  404. bool mIsContinuingFromException;
  405. Array<int64> mTempBreakpoint;
  406. Array<int64> mStepBreakpointAddrs;
  407. addr_target mSavedBreakpointAddressContinuing;
  408. addr_target mSavedAtBreakpointAddress;
  409. BF_CONTEXT mSavedContext;
  410. Dictionary<int, Profiler*> mPendingProfilerMap;
  411. Array<Profiler*> mNewProfilerList;
  412. addr_target mMemCacheAddr;
  413. uint8 mMemCacheData[WD_MEMCACHE_SIZE];
  414. public:
  415. void Fail(const StringImpl& error);
  416. void TryGetThreadName(WdThreadInfo* threadInfo);
  417. void ThreadRestorePause(WdThreadInfo* onlyPauseThread, WdThreadInfo* dontPauseThread);
  418. void ThreadRestoreUnpause();
  419. void UpdateThreadDebugRegisters(WdThreadInfo* threadInfo);
  420. void UpdateThreadDebugRegisters();
  421. void PhysSetBreakpoint(addr_target address);
  422. void SetBreakpoint(addr_target address, bool fromRehup = false);
  423. void SetTempBreakpoint(addr_target address);
  424. void PhysRemoveBreakpoint(addr_target address);
  425. void RemoveBreakpoint(addr_target address);
  426. void SingleStepX86();
  427. bool IsInRunState();
  428. bool ContinueFromBreakpoint();
  429. bool HasLineInfoAt(addr_target address);
  430. DbgLineData* FindLineDataAtAddress(addr_target address, DbgSubprogram** outSubProgram = NULL, DbgSrcFile** outSrcFile = NULL, int* outLineIdx = NULL, DbgOnDemandKind onDemandKind = DbgOnDemandKind_AllowRemote);
  431. DbgLineData* FindLineDataInSubprogram(addr_target address, DbgSubprogram* dwSubprogram);
  432. bool IsStepFiltered(DbgSubprogram* dbgSubprogram, DbgLineData* dbgLineData);
  433. void RemoveTempBreakpoints();
  434. void RehupBreakpoints(bool doFlush);
  435. bool WantsBreakpointAt(addr_target address);
  436. void CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFile, int lineNum, int hotIdx);
  437. void CheckBreakpoint(WdBreakpoint* wdBreakpoint);
  438. bool IsMemoryBreakpointSizeValid(addr_target addr, int size);
  439. bool HasMemoryBreakpoint(addr_target addr, int size);
  440. bool PopulateRegisters(CPURegisters* registers, BF_CONTEXT& lcContext);
  441. virtual bool PopulateRegisters(CPURegisters* registers);
  442. bool RollBackStackFrame(CPURegisters* registers, bool isStackStart);
  443. bool SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget, int newTargetSize);
  444. DbgSubprogram* TryFollowHotJump(DbgSubprogram* subprogram, addr_target addr);
  445. bool ParseFormatInfo(DbgModule* dbgModule, const StringImpl& formatInfoStr, DwFormatInfo* formatInfo, BfPassInstance* bfPassInstance, int* assignExprOffset, String* assignExpr = NULL, String* errorString = NULL, DbgTypedValue contextTypedValue = DbgTypedValue());
  446. String MaybeQuoteFormatInfoParam(const StringImpl& str);
  447. void DbgVisFailed(DebugVisualizerEntry* debugVis, const StringImpl& evalString, const StringImpl& errors);
  448. DbgTypedValue EvaluateInContext(DbgCompileUnit* dbgCompileUnit, const DbgTypedValue& contextTypedValue, const StringImpl& subExpr, DwFormatInfo* formatInfo = NULL, String* outReferenceId = NULL, String* outErrors = NULL);
  449. bool EvalCondition(DebugVisualizerEntry* debugVis, DbgCompileUnit* dbgCompileUnit, DbgTypedValue typedVal, DwFormatInfo& formatInfo, const StringImpl& condition, const Array<String>& dbgVisWildcardCaptures, String& errorStr);
  450. DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId);
  451. void ProcessEvalString(DbgCompileUnit* dbgCompileUnit, DbgTypedValue useTypedValue, String& evalStr, String& displayString, DwFormatInfo& formatInfo, DebugVisualizerEntry* debugVis, bool limitLength);
  452. String ReadString(DbgTypeCode charType, intptr addr, bool isLocalAddr, int maxLength, DwFormatInfo& formatInfo);
  453. String DbgTypedValueToString(const DbgTypedValue& typedValue, const StringImpl& expr, DwFormatInfo& formatFlags, DbgExprEvaluator* optEvaluator, bool fullPrecision = false);
  454. bool ShouldShowStaticMember(DbgType* dbgType, DbgVariable* member);
  455. String GetMemberList(DbgType* dbgType, const StringImpl& expr, bool isPtr, bool isStatic, bool forceCast = false, bool isSplat = false, bool isReadOnly = false);
  456. DebugVisualizerEntry* FindVisualizerForType(DbgType* dbgType, Array<String>* wildcardCaptures);
  457. void ReserveHotTargetMemory(int size);
  458. addr_target AllocHotTargetMemory(int size, bool canExecute, bool canWrite, int* outAllocSize);
  459. void ReleaseHotTargetMemory(addr_target addr, int size);
  460. void CleanupHotHeap();
  461. int EnableWriting(intptr address, int size);
  462. int SetProtection(intptr address, int size, int prot);
  463. void EnableMemCache();
  464. void DisableMemCache();
  465. template<typename T> T ReadMemory(intptr addr, bool local = false, bool* failed = NULL);
  466. bool WriteInstructions(intptr address, void* src, uint64 length);
  467. template<typename T> bool WriteMemory(intptr addr, T val);
  468. virtual DbgMemoryFlags GetMemoryFlags(intptr address) override;
  469. void SetRunState(RunState runState);
  470. bool IsPaused();
  471. void ClearStep();
  472. bool SetupStep(StepType stepType);
  473. void CheckNonDebuggerBreak();
  474. bool HasSteppedIntoCall();
  475. void StepLineTryPause(addr_target address, bool requireExactMatch);
  476. void PushValue(CPURegisters* registers, int64 val);
  477. void PushValue(CPURegisters* registers, const DbgTypedValue& typedValue);
  478. void SetThisRegister(CPURegisters* registers, addr_target val);
  479. void AddParamValue(int paramIdx, bool hadThis, CPURegisters* registers, const DbgTypedValue& typedValue);
  480. bool CheckNeedsSRetArgument(DbgType* retType);
  481. DbgTypedValue ReadReturnValue(CPURegisters* registers, DbgType* type);
  482. bool SetRegisters(CPURegisters* registers);
  483. void SaveAllRegisters();
  484. void RestoreAllRegisters();
  485. String GetArrayItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData);
  486. String GetLinkedListItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, addr_target endNodePtr, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData);
  487. String GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgTypedValue dictValue, int bucketIdx, int nodeIdx, int& count, String* outContinuationData);
  488. String GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, Array<addr_target>& parentList, DbgType*& valueType, DbgTypedValue& curNode, int count, String* outContinuationData);
  489. void HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgType* dwUseType, DbgType* dwValueType, String& ptrUseDataStr, String& ptrDataStr, DbgTypedValue useTypedValue, Array<String>& dbgVisWildcardCaptures, DwFormatInfo& formatInfo);
  490. void ModuleChanged(DbgModule* dbgModule);
  491. bool DoUpdate();
  492. void DebugThreadProc();
  493. bool DoOpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock);
  494. DbgTypedValue GetRegister(const StringImpl& regName, DbgLanguage language, CPURegisters* registers, Array<RegForm>* regForms = NULL);
  495. void FixupLineData(DbgCompileUnit* compileUnit);
  496. void FixupLineDataForSubprogram(DbgSubprogram* subProgram);
  497. DbgModule* GetCallStackDbgModule(int callStackIdx);
  498. DbgSubprogram* GetCallStackSubprogram(int callStackIdx);
  499. DbgCompileUnit* GetCallStackCompileUnit(int callStackIdx);
  500. String Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags);
  501. String EvaluateContinue() override;
  502. void EvaluateContinueKeep() override;
  503. String EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance& bfPassInstance);
  504. String GetAutocompleteOutput(DwAutoComplete& autoComplete);
  505. bool CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubprogram* dbgSubprogram, addr_target pcAddress);
  506. void CleanupDebugEval(bool restoreRegisters = true);
  507. bool FixCallStackIdx(int& callStackIdx);
  508. virtual int LoadDebugInfoForModule(DbgModule* dbgModule);
  509. virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName);
  510. public:
  511. WinDebugger(DebugManager* debugManager);
  512. virtual ~WinDebugger();
  513. virtual void OutputMessage(const StringImpl& msg) override;
  514. virtual void OutputRawMessage(const StringImpl& msg) override;
  515. virtual int GetAddrSize() override;
  516. virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) override;
  517. virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock) override;
  518. virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override;
  519. virtual void Run() override;
  520. virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) override;
  521. virtual void InitiateHotResolve(DbgHotResolveFlags flags) override;
  522. virtual void Update() override;
  523. virtual void ContinueDebugEvent() override;
  524. virtual void ForegroundTarget() override;
  525. virtual Breakpoint* CreateBreakpoint(const StringImpl& fileName, int lineNum, int wantColumn, int instrOffset) override;
  526. virtual Breakpoint* CreateMemoryBreakpoint(intptr addr, int byteCount) override;
  527. virtual Breakpoint* CreateSymbolBreakpoint(const StringImpl& symbolName) override;
  528. virtual Breakpoint* CreateAddressBreakpoint(intptr address) override;
  529. virtual void CheckBreakpoint(Breakpoint* breakpoint) override;
  530. virtual void HotBindBreakpoint(Breakpoint* breakpoint, int lineNum, int hotIdx) override;
  531. virtual void DeleteBreakpoint(Breakpoint* breakpoint) override;
  532. virtual void DetachBreakpoint(Breakpoint* breakpoint) override;
  533. virtual void MoveBreakpoint(Breakpoint* breakpoint, int lineNum, int wantColumn, bool rebindNow) override;
  534. virtual void MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int byteCount) override;
  535. virtual void DisableBreakpoint(Breakpoint* breakpoint) override;
  536. virtual void SetBreakpointCondition(Breakpoint* breakpoint, const StringImpl& condition) override;
  537. virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) override;
  538. virtual Breakpoint* FindBreakpointAt(intptr address) override;
  539. virtual Breakpoint* GetActiveBreakpoint() override;
  540. virtual void BreakAll() override;
  541. virtual bool TryRunContinue() override;
  542. virtual void StepInto(bool inAssembly) override;
  543. virtual void StepIntoSpecific(intptr addr) override;
  544. virtual void StepOver(bool inAssembly) override;
  545. virtual void StepOut(bool inAssembly) override;
  546. virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) override;
  547. virtual String Evaluate(const StringImpl& expr, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) override;
  548. virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) override;
  549. virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) override;
  550. virtual bool AssignToReg(int callStackIdx, DbgTypedValue reg, DbgTypedValue value, String& outError);
  551. virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) override;
  552. virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) override;
  553. virtual String GetAutoLocals(int callStackIdx, bool showRegs) override;
  554. virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) override;
  555. virtual String GetThreadInfo() override;
  556. virtual void SetActiveThread(int threadId) override;
  557. virtual int GetActiveThread() override;
  558. virtual void FreezeThread(int threadId) override;
  559. virtual void ThawThread(int threadId) override;
  560. virtual bool IsActiveThreadWaiting() override;
  561. virtual void ClearCallStack() override;
  562. virtual void UpdateCallStack(bool slowEarlyOut = true) override;
  563. virtual int GetCallStackCount() override;
  564. virtual int GetRequestedStackFrameIdx() override;
  565. virtual int GetBreakStackFrameIdx() override;
  566. virtual bool ReadMemory(intptr address, uint64 length, void* dest, bool local = false) override;
  567. virtual bool WriteMemory(intptr address, void* src, uint64 length) override;
  568. addr_target GetTLSOffset(int tlsIndex);
  569. virtual void UpdateRegisterUsage(int stackFrameIdx) override;
  570. virtual void UpdateCallStackMethod(int stackFrameIdx) override;
  571. virtual void GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override;
  572. virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) override;
  573. 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;
  574. virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) override;
  575. virtual int GetJmpState(int stackFrameIdx) override;
  576. virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) override;
  577. virtual String GetStackMethodOwner(int stackFrameIdx, int& language) override;
  578. virtual String FindCodeAddresses(const StringImpl& fileName, int line, int column, bool allowAutoResolve) override;
  579. virtual String GetAddressSourceLocation(intptr address) override;
  580. virtual String GetAddressSymbolName(intptr address, bool demangle) override;
  581. virtual String DisassembleAtRaw(intptr address) override;
  582. virtual String DisassembleAt(intptr address) override;
  583. virtual String FindLineCallAddresses(intptr address) override;
  584. virtual String GetCurrentException() override;
  585. virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) override;
  586. virtual String GetModulesInfo() override;
  587. virtual void CancelSymSrv() override;
  588. virtual bool HasPendingDebugLoads() override;
  589. virtual int LoadDebugInfoForModule(const StringImpl& moduleName) override;
  590. virtual void StopDebugging() override;
  591. virtual void Terminate() override;
  592. virtual void Detach() override;
  593. virtual Profiler* StartProfiling() override;
  594. virtual Profiler* PopProfiler() override;
  595. virtual void ReportMemory(MemReporter* memReporter) override;
  596. virtual bool IsOnDemandDebugger() override { return false; }
  597. virtual bool IsMiniDumpDebugger() { return false; }
  598. };
  599. template<typename T> bool WinDebugger::WriteMemory(intptr addr, T val)
  600. {
  601. SIZE_T dwWriteBytes;
  602. return WriteProcessMemory(mProcessInfo.hProcess, (void*)(intptr)addr, &val, (SIZE_T)sizeof(T), &dwWriteBytes) != 0;
  603. }
  604. template<typename T> T WinDebugger::ReadMemory(intptr addr, bool local, bool* failed)
  605. {
  606. bool success = true;
  607. T val;
  608. memset(&val, 0, sizeof(T));
  609. if (local)
  610. {
  611. if (addr != 0)
  612. {
  613. memcpy(&val, (void*)(intptr)addr, sizeof(T));
  614. /*__try
  615. {
  616. memcpy(&val, (void*)(intptr)addr, sizeof(T));
  617. }
  618. __except (EXCEPTION_EXECUTE_HANDLER)
  619. {
  620. success = false;
  621. }*/
  622. }
  623. else
  624. success = false;
  625. }
  626. else
  627. {
  628. //SIZE_T dwReadBytes;
  629. memset(&val, 0, sizeof(T));
  630. //success = ReadProcessMemory(mProcessInfo.hProcess, (void*)(intptr)addr, &val, (SIZE_T)sizeof(T), &dwReadBytes) != 0;
  631. success = ReadMemory(addr, (int)sizeof(T), &val);
  632. }
  633. if (failed != NULL)
  634. *failed = !success;
  635. return val;
  636. }
  637. addr_target DecodeTargetDataPtr(const char*& strRef);
  638. NS_BF_DBG_END