CeDebugger.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #pragma once
  2. #include "BfSystem.h"
  3. #include "BfModule.h"
  4. #include "BeefySysLib/util/Heap.h"
  5. #include "BeefySysLib/util/AllocDebug.h"
  6. #include "../Debugger.h"
  7. NS_BF_BEGIN
  8. class BfCompiler;
  9. class CeFrame;
  10. class CeExprEvaluator;
  11. class CeContext;
  12. class CeMachine;
  13. class CeFunction;
  14. class BfReducer;
  15. class CeDebugger;
  16. class DebugVisualizerEntry;
  17. class CeEvaluationContext;
  18. class CeBreakpointCondition
  19. {
  20. public:
  21. CeEvaluationContext* mDbgEvaluationContext;
  22. String mExpr;
  23. ~CeBreakpointCondition();
  24. };
  25. class CeBreakpoint : public Breakpoint
  26. {
  27. public:
  28. uintptr mCurBindAddr;
  29. bool mHasBound;
  30. int mIdx;
  31. CeBreakpointCondition* mCondition;
  32. public:
  33. CeBreakpoint()
  34. {
  35. mCurBindAddr = 1;
  36. mHasBound = false;
  37. mIdx = -1;
  38. mCondition = NULL;
  39. }
  40. ~CeBreakpoint();
  41. virtual uintptr GetAddr() { return mCurBindAddr; }
  42. virtual bool IsMemoryBreakpointBound() { return false; }
  43. };
  44. struct CeFormatInfo
  45. {
  46. int mCallStackIdx;
  47. bool mHidePointers;
  48. bool mIgnoreDerivedClassInfo;
  49. bool mNoVisualizers;
  50. bool mNoMembers;
  51. bool mRawString;
  52. bool mNoEdit;
  53. DbgTypeKindFlags mTypeKindFlags;
  54. intptr mArrayLength;
  55. intptr mOverrideCount;
  56. intptr mMaxCount;
  57. DwDisplayType mDisplayType;
  58. int mTotalSummaryLength;
  59. String mReferenceId;
  60. String mSubjectExpr;
  61. String mExpectedType;
  62. String mNamespaceSearch;
  63. int mExpandItemDepth;
  64. BfTypedValue mExplicitThis;
  65. CeFormatInfo()
  66. {
  67. mCallStackIdx = -1;
  68. mHidePointers = false;
  69. mIgnoreDerivedClassInfo = false;
  70. mRawString = false;
  71. mNoVisualizers = false;
  72. mNoMembers = false;
  73. mNoEdit = false;
  74. mTypeKindFlags = DbgTypeKindFlag_None;
  75. mArrayLength = -1;
  76. mOverrideCount = -1;
  77. mMaxCount = -1;
  78. mTotalSummaryLength = 0;
  79. mDisplayType = DwDisplayType_NotSpecified;
  80. mExpandItemDepth = 0;
  81. }
  82. };
  83. class CeEvaluationContext
  84. {
  85. public:
  86. CeDebugger* mDebugger;
  87. BfParser* mParser;
  88. BfReducer* mReducer;
  89. BfPassInstance* mPassInstance;
  90. BfExprEvaluator* mExprEvaluator;
  91. BfExpression* mExprNode;
  92. BfTypedValue mResultOverride;
  93. String mExprString;
  94. BfTypedValue mExplicitThis;
  95. int mCallStackIdx;
  96. public:
  97. CeEvaluationContext(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo = NULL, BfTypedValue contextValue = BfTypedValue());
  98. void Init(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo = NULL, BfTypedValue contextValue = BfTypedValue());
  99. bool HasExpression();
  100. ~CeEvaluationContext();
  101. BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue, CeDbgState* dbgState = NULL);
  102. String GetErrorStr();
  103. bool HadError();
  104. };
  105. class CeDbgState
  106. {
  107. public:
  108. CeFrame* mActiveFrame;
  109. CeContext* mCeContext;
  110. BfTypedValue mExplicitThis;
  111. DwEvalExpressionFlags mDbgExpressionFlags;
  112. CeFormatInfo* mFormatInfo;
  113. bool mHadSideEffects;
  114. bool mBlockedSideEffects;
  115. bool mReferencedIncompleteTypes;
  116. public:
  117. CeDbgState()
  118. {
  119. mActiveFrame = NULL;
  120. mCeContext = NULL;
  121. mFormatInfo = NULL;
  122. mDbgExpressionFlags = DwEvalExpressionFlag_None;
  123. mHadSideEffects = false;
  124. mBlockedSideEffects = false;
  125. mReferencedIncompleteTypes = false;
  126. }
  127. };
  128. class CePendingExpr
  129. {
  130. public:
  131. int mThreadId;
  132. BfPassInstance* mPassInstance;
  133. BfParser* mParser;
  134. BfType* mExplitType;
  135. CeFormatInfo mFormatInfo;
  136. DwEvalExpressionFlags mExpressionFlags;
  137. int mCursorPos;
  138. BfAstNode* mExprNode;
  139. String mReferenceId;
  140. int mCallStackIdx;
  141. String mResult;
  142. int mIdleTicks;
  143. String mException;
  144. bool mDone;
  145. CePendingExpr();
  146. ~CePendingExpr();
  147. };
  148. class CeDbgStackInfo
  149. {
  150. public:
  151. int mFrameIdx;
  152. int mScopeIdx;
  153. int mInlinedFrom;
  154. };
  155. class CeFileInfo
  156. {
  157. public:
  158. Array<CeBreakpoint*> mOrderedBreakpoints;
  159. };
  160. class CeDbgFieldEntry
  161. {
  162. public:
  163. BfType* mType;
  164. int mDataOffset;
  165. public:
  166. CeDbgFieldEntry()
  167. {
  168. mType = NULL;
  169. mDataOffset = 0;
  170. }
  171. };
  172. class CeDbgTypeInfo
  173. {
  174. public:
  175. struct ConstIntEntry
  176. {
  177. public:
  178. int mFieldIdx;
  179. int64 mVal;
  180. };
  181. public:
  182. BfType* mType;
  183. Array<CeDbgFieldEntry> mFieldOffsets;
  184. Array<ConstIntEntry> mConstIntEntries;
  185. };
  186. struct CeTypedValue
  187. {
  188. int64 mAddr;
  189. BfIRType mType;
  190. CeTypedValue()
  191. {
  192. mAddr = 0;
  193. mType = BfIRType();
  194. }
  195. CeTypedValue(int64 addr, BfIRType type)
  196. {
  197. mAddr = addr;
  198. mType = type;
  199. }
  200. operator bool() const
  201. {
  202. return mType.mKind != BfIRTypeData::TypeKind_None;
  203. }
  204. };
  205. enum CeTypeModKind
  206. {
  207. CeTypeModKind_Normal,
  208. CeTypeModKind_Const,
  209. CeTypeModKind_ReadOnly
  210. };
  211. class CeDebugger : public Debugger
  212. {
  213. public:
  214. BfCompiler* mCompiler;
  215. CeMachine* mCeMachine;
  216. DebugManager* mDebugManager;
  217. CePendingExpr* mDebugPendingExpr;
  218. CeDbgState* mCurDbgState;
  219. Array<CeBreakpoint*> mBreakpoints;
  220. Dictionary<String, CeFileInfo*> mFileInfo;
  221. Dictionary<int, CeDbgTypeInfo> mDbgTypeInfoMap;
  222. Array<CeDbgStackInfo> mDbgCallStack;
  223. CeEvaluationContext* mCurEvaluationContext;
  224. CeBreakpoint* mActiveBreakpoint;
  225. int mBreakpointVersion;
  226. bool mBreakpointCacheDirty;
  227. bool mBreakpointFramesDirty;
  228. int mCurDisasmFuncId;
  229. int mPendingActiveFrameOffset;
  230. public:
  231. template<typename T> T ReadMemory(intptr addr, bool* failed = NULL)
  232. {
  233. T val;
  234. memset(&val, 0, sizeof(T));
  235. bool success = ReadMemory(addr, (int)sizeof(T), &val);
  236. if (failed != NULL)
  237. *failed = !success;
  238. return val;
  239. }
  240. bool CheckConditionalBreakpoint(CeBreakpoint* breakpoint);
  241. bool SetupStep(int frameIdx = 0);
  242. CeFrame* GetFrame(int callStackIdx);
  243. String DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread);
  244. String Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags);
  245. DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId);
  246. String GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, bool isStatic);
  247. DebugVisualizerEntry* FindVisualizerForType(BfType* dbgType, Array<String>* wildcardCaptures);
  248. bool ParseFormatInfo(const StringImpl& formatInfoStr, CeFormatInfo* formatInfo, BfPassInstance* bfPassInstance, int* assignExprOffset, String* assignExprString, String* errorString, BfTypedValue contextTypedValue = BfTypedValue());
  249. String MaybeQuoteFormatInfoParam(const StringImpl& str);
  250. BfTypedValue EvaluateInContext(const BfTypedValue& contextTypedValue, const StringImpl& subExpr, CeFormatInfo* formatInfo = NULL, String* outReferenceId = NULL, String* outErrors = NULL);
  251. void DbgVisFailed(DebugVisualizerEntry* debugVis, const StringImpl& evalString, const StringImpl& errors);
  252. String GetArrayItems(DebugVisualizerEntry* debugVis, BfType* valueType, BfTypedValue& curNode, int& count, String* outContinuationData);
  253. String GetLinkedListItems(DebugVisualizerEntry* debugVis, addr_ce endNodePtr, BfType* valueType, BfTypedValue& curNode, int& count, String* outContinuationData);
  254. String GetDictionaryItems(DebugVisualizerEntry* debugVis, BfTypedValue dictValue, int bucketIdx, int nodeIdx, int& count, String* outContinuationData);
  255. String GetTreeItems(DebugVisualizerEntry* debugVis, Array<addr_ce>& parentList, BfType*& valueType, BfTypedValue& curNode, int count, String* outContinuationData);
  256. bool EvalCondition(DebugVisualizerEntry* debugVis, BfTypedValue typedVal, CeFormatInfo& formatInfo, const StringImpl& condition, const Array<String>& dbgVisWildcardCaptures, String& errorStr);
  257. CeTypedValue GetAddr(BfConstant* constant, BfType* type = NULL);
  258. CeTypedValue GetAddr(const BfTypedValue typeVal);
  259. String ReadString(BfTypeCode charType, intptr addr, intptr maxLength, CeFormatInfo& formatInfo);
  260. void ProcessEvalString(BfTypedValue useTypedValue, String& evalStr, String& displayString, CeFormatInfo& formatInfo, DebugVisualizerEntry* debugVis, bool limitLength);
  261. String TypedValueToString(const BfTypedValue& typedValue, const StringImpl& expr, CeFormatInfo& formatFlags, bool fullPrecision = false, CeTypeModKind typeModKind = CeTypeModKind_Normal);
  262. void HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* debugVis, BfTypedValue typedValue, addr_ce addr, addr_ce addrInst, Array<String>& dbgVisWildcardCaptures, CeFormatInfo& formatInfo);
  263. String GetAutocompleteOutput(BfAutoComplete& autoComplete);
  264. void ClearBreakpointCache();
  265. void UpdateBreakpointCache();
  266. void UpdateBreakpointFrames();
  267. void UpdateBreakpointAddrs();
  268. void UpdateBreakpoints(CeFunction* ceFunction);
  269. void Continue();
  270. CeDbgTypeInfo* GetDbgTypeInfo(int typeId);
  271. CeDbgTypeInfo* GetDbgTypeInfo(BfIRType irType);
  272. int64 ValueToInt(addr_ce addr, BfType* type);
  273. int64 ValueToInt(const BfTypedValue& typedVal);
  274. BfType* FindType(const StringImpl& name);
  275. String TypeToString(const BfTypedValue& typedValue);
  276. String TypeToString(BfType* type, CeTypeModKind typeModKind);
  277. public:
  278. CeDebugger(DebugManager* debugManager, BfCompiler* bfCompiler);
  279. ~CeDebugger();
  280. virtual void OutputMessage(const StringImpl& msg) override;
  281. virtual void OutputRawMessage(const StringImpl& msg) override;
  282. virtual int GetAddrSize() override;
  283. virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) override;
  284. virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock, bool hotSwapEnabled, DbgOpenFileFlags openFileFlags) override;
  285. virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override;
  286. virtual void GetStdHandles(BfpFile** outStdIn, BfpFile** outStdOut, BfpFile** outStdErr) override;
  287. virtual void Run() override;
  288. virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) override;
  289. virtual void InitiateHotResolve(DbgHotResolveFlags flags) override;
  290. virtual intptr GetDbgAllocHeapSize() override;
  291. virtual String GetDbgAllocInfo() override;
  292. virtual void Update() override;
  293. virtual void ContinueDebugEvent() override;
  294. virtual void ForegroundTarget(int altProcessId) override;
  295. virtual Breakpoint* CreateBreakpoint(const StringImpl& fileName, int lineNum, int wantColumn, int instrOffset) override;
  296. virtual Breakpoint* CreateMemoryBreakpoint(intptr addr, int byteCount) override;
  297. virtual Breakpoint* CreateSymbolBreakpoint(const StringImpl& symbolName) override;
  298. virtual Breakpoint* CreateAddressBreakpoint(intptr address) override;
  299. virtual uintptr GetBreakpointAddr(Breakpoint* breakpoint) override;
  300. virtual void CheckBreakpoint(Breakpoint* breakpoint) override;
  301. virtual void HotBindBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int hotIdx) override;
  302. virtual void DeleteBreakpoint(Breakpoint* wdBreakpoint) override;
  303. virtual void DetachBreakpoint(Breakpoint* wdBreakpoint) override;
  304. virtual void MoveBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int wantColumn, bool rebindNow) override;
  305. virtual void MoveMemoryBreakpoint(Breakpoint* wdBreakpoint, intptr addr, int byteCount) override;
  306. virtual void DisableBreakpoint(Breakpoint* wdBreakpoint) override;
  307. virtual void SetBreakpointCondition(Breakpoint* wdBreakpoint, const StringImpl& condition) override;
  308. virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) override;
  309. virtual Breakpoint* FindBreakpointAt(intptr address) override;
  310. virtual Breakpoint* GetActiveBreakpoint() override;
  311. virtual void BreakAll() override;
  312. virtual bool TryRunContinue() override;
  313. virtual void StepInto(bool inAssembly) override;
  314. virtual void StepIntoSpecific(intptr addr) override;
  315. virtual void StepOver(bool inAssembly) override;
  316. virtual void StepOut(bool inAssembly) override;
  317. virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) override;
  318. //virtual DbgTypedValue GetRegister(const StringImpl& regName, CPURegisters* registers, Array<RegForm>* regForms = NULL) override;
  319. virtual String Evaluate(const StringImpl& expr, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) override;
  320. virtual String EvaluateContinue() override;
  321. virtual void EvaluateContinueKeep() override;
  322. virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) override;
  323. virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) override;
  324. virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) override;
  325. virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) override;
  326. virtual String GetAutoLocals(int callStackIdx, bool showRegs) override;
  327. virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) override;
  328. virtual String GetProcessInfo() override;
  329. virtual int GetProcessId() override;
  330. virtual String GetThreadInfo() override;
  331. virtual void SetActiveThread(int threadId) override;
  332. virtual int GetActiveThread() override;
  333. virtual void FreezeThread(int threadId) override;
  334. virtual void ThawThread(int threadId) override;
  335. virtual bool IsActiveThreadWaiting() override;
  336. virtual void ClearCallStack() override;
  337. virtual void UpdateCallStack(bool slowEarlyOut = true) override;
  338. virtual int GetCallStackCount() override;
  339. virtual int GetRequestedStackFrameIdx() override;
  340. virtual int GetBreakStackFrameIdx() override;
  341. virtual bool ReadMemory(intptr address, uint64 length, void* dest, bool local = false) override;
  342. virtual bool WriteMemory(intptr address, void* src, uint64 length) override;
  343. virtual DbgMemoryFlags GetMemoryFlags(intptr address) override;
  344. virtual void UpdateRegisterUsage(int stackFrameIdx) override;
  345. virtual void UpdateCallStackMethod(int stackFrameIdx) override;
  346. virtual void GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override;
  347. virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) override;
  348. 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) override;
  349. virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) override;
  350. virtual int GetJmpState(int stackFrameIdx) override;
  351. virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) override;
  352. virtual String GetStackMethodOwner(int stackFrameIdx, int& language) override;
  353. virtual String FindCodeAddresses(const StringImpl& fileName, int line, int column, bool allowAutoResolve) override;
  354. virtual String GetAddressSourceLocation(intptr address) override;
  355. virtual String GetAddressSymbolName(intptr address, bool demangle) override;
  356. virtual String DisassembleAtRaw(intptr address) override;
  357. virtual String DisassembleAt(intptr address) override;
  358. virtual String FindLineCallAddresses(intptr address) override;
  359. virtual String GetCurrentException() override;
  360. virtual String GetModulesInfo() override;
  361. virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) override;
  362. virtual void CancelSymSrv() override;
  363. virtual bool HasPendingDebugLoads() override;
  364. virtual int LoadImageForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override;
  365. virtual int LoadDebugInfoForModule(const StringImpl& moduleName) override;
  366. virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override;
  367. virtual void StopDebugging() override;
  368. virtual void Terminate() override;
  369. virtual void Detach() override;
  370. virtual Profiler* StartProfiling() override;
  371. virtual Profiler* PopProfiler() override; // Profiler requested by target program
  372. virtual void ReportMemory(MemReporter* memReporter) override;
  373. virtual bool IsOnDemandDebugger() override;
  374. virtual bool GetEmitSource(const StringImpl& filePath, String& outText) override;
  375. };
  376. NS_BF_END