Debugger.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. #pragma once
  2. #include "DebugCommon.h"
  3. #include "Compiler/MemReporter.h"
  4. #include "BeefySysLib/util/HashSet.h"
  5. #include <vector>
  6. NS_BF_BEGIN
  7. class DebugManager;
  8. class BfAutoComplete;
  9. enum DbgHitCountBreakKind : int8
  10. {
  11. DbgHitCountBreakKind_None,
  12. DbgHitCountBreakKind_Equals,
  13. DbgHitCountBreakKind_GreaterEquals,
  14. DbgHitCountBreakKind_Multiple
  15. };
  16. class Breakpoint
  17. {
  18. public:
  19. String mFilePath;
  20. int mRequestedLineNum;
  21. int mLineNum;
  22. int mColumn;
  23. int mInstrOffset;
  24. int mPendingHotBindIdx;
  25. int mHitCount;
  26. int mTargetHitCount;
  27. DbgHitCountBreakKind mHitCountBreakKind;
  28. String mLogging;
  29. bool mBreakAfterLogging;
  30. intptr mThreadId;
  31. String mSymbolName;
  32. Breakpoint* mHead;
  33. Breakpoint* mLinkedSibling; // For things like templates with multiple imps on same source line
  34. bool mIsLinkedSibling; // Not in breakpoint list
  35. public:
  36. Breakpoint()
  37. {
  38. mRequestedLineNum = -1;
  39. mLineNum = -1;
  40. mColumn = -1;
  41. mInstrOffset = 0;
  42. mPendingHotBindIdx = -1;
  43. mHitCount = 0;
  44. mTargetHitCount = 0;
  45. mHitCountBreakKind = DbgHitCountBreakKind_None;
  46. mThreadId = -1;
  47. mHead = NULL;
  48. mLinkedSibling = NULL;
  49. mIsLinkedSibling = false;
  50. mBreakAfterLogging = false;
  51. }
  52. virtual uintptr GetAddr() = 0;
  53. virtual bool IsMemoryBreakpointBound() = 0;
  54. };
  55. enum DbgTypeKindFlags
  56. {
  57. DbgTypeKindFlag_None = 0,
  58. DbgTypeKindFlag_Int = 1
  59. };
  60. enum DwDisplayType : int8
  61. {
  62. DwDisplayType_NotSpecified,
  63. DwDisplayType_Decimal,
  64. DwDisplayType_HexLower,
  65. DwDisplayType_HexUpper,
  66. DwDisplayType_Char,
  67. DwDisplayType_Ascii,
  68. DwDisplayType_Utf8,
  69. DwDisplayType_Utf16,
  70. DwDisplayType_Utf32,
  71. };
  72. enum DwIntDisplayType : int8
  73. {
  74. DwIntDisplayType_Default,
  75. DwIntDisplayType_Decimal,
  76. DwIntDisplayType_HexadecimalUpper,
  77. DwIntDisplayType_Binary,
  78. DwIntDisplayType_Octal,
  79. DwIntDisplayType_HexadecimalLower,
  80. };
  81. enum DwFloatDisplayType : int8
  82. {
  83. DwFloatDisplayType_Default,
  84. DwFloatDisplayType_Minimal,
  85. DwFloatDisplayType_Full,
  86. DwFloatDisplayType_HexUpper,
  87. DwFloatDisplayType_HexLower,
  88. };
  89. enum DwMmDisplayType : int8
  90. {
  91. DwMmDisplayType_Default,
  92. DwMmDisplayType_UInt8,
  93. DwMmDisplayType_Int16,
  94. DwMmDisplayType_Int32,
  95. DwMmDisplayType_Int64,
  96. DwMmDisplayType_Float,
  97. DwMmDisplayType_Double
  98. };
  99. enum DwEvalExpressionFlags : int16
  100. {
  101. DwEvalExpressionFlag_None = 0,
  102. DwEvalExpressionFlag_FullPrecision = 0x01,
  103. DwEvalExpressionFlag_ValidateOnly = 0x02,
  104. DwEvalExpressionFlag_DeselectCallStackIdx = 0x04,
  105. DwEvalExpressionFlag_AllowSideEffects = 0x08,
  106. DwEvalExpressionFlag_AllowCalls = 0x10,
  107. DwEvalExpressionFlag_AllowPropertyEval = 0x20,
  108. DwEvalExpressionFlag_MemoryAddress = 0x40,
  109. DwEvalExpressionFlag_MemoryWatch = 0x80,
  110. DwEvalExpressionFlag_Symbol = 0x100,
  111. DwEvalExpressionFlag_StepIntoCalls = 0x200,
  112. DwEvalExpressionFlag_RawStr = 0x400,
  113. DwEvalExpressionFlag_AllowStringView = 0x800
  114. };
  115. struct DwDisplayInfo
  116. {
  117. String mFormatStr;
  118. DwIntDisplayType mIntDisplayType;
  119. DwMmDisplayType mMmDisplayType;
  120. DwFloatDisplayType mFloatDisplayType;
  121. DwDisplayInfo()
  122. {
  123. mIntDisplayType = DwIntDisplayType_Default;
  124. mMmDisplayType = DwMmDisplayType_Default;
  125. mFloatDisplayType = DwFloatDisplayType_Default;
  126. }
  127. };
  128. enum RunState
  129. {
  130. RunState_NotStarted,
  131. RunState_Running,
  132. RunState_Running_ToTempBreakpoint,
  133. RunState_Paused,
  134. RunState_Breakpoint,
  135. RunState_DebugEval,
  136. RunState_DebugEval_Done,
  137. RunState_HotStep,
  138. RunState_Exception,
  139. RunState_Terminating,
  140. RunState_Terminated,
  141. RunState_SearchingSymSrv,
  142. RunState_HotResolve,
  143. RunState_TargetUnloaded
  144. };
  145. enum DebuggerResult
  146. {
  147. DebuggerResult_Ok,
  148. DebuggerResult_UnknownError,
  149. DebuggerResult_CannotOpen,
  150. DebuggerResult_WrongBitSize,
  151. };
  152. enum BfDbgAttachFlags : uint8
  153. {
  154. BfDbgAttachFlag_None = 0,
  155. BfDbgAttachFlag_ShutdownOnExit = 1
  156. };
  157. enum BfSymSrvFlags : uint8
  158. {
  159. BfSymSrvFlag_None = 0,
  160. BfSymSrvFlag_Disable = 1,
  161. BfSymSrvFlag_TempCache = 2, // For testing - set up clean temporary cache
  162. };
  163. enum DbgHotResolveFlags : uint8
  164. {
  165. DbgHotResolveFlag_None = 0,
  166. DbgHotResolveFlag_ActiveMethods = 1,
  167. DbgHotResolveFlag_Allocations = 2,
  168. DbgHotResolveFlag_KeepThreadState = 4
  169. };
  170. enum DbgMemoryFlags : uint8
  171. {
  172. DbgMemoryFlags_None = 0,
  173. DbgMemoryFlags_Read = 1,
  174. DbgMemoryFlags_Write = 2,
  175. DbgMemoryFlags_Execute = 4
  176. };
  177. enum DbgOpenFileFlags : uint8
  178. {
  179. DbgOpenFileFlag_None = 0,
  180. DbgOpenFileFlag_RedirectStdInput = 1,
  181. DbgOpenFileFlag_RedirectStdOutput = 2,
  182. DbgOpenFileFlag_RedirectStdError = 4
  183. };
  184. class DbgModuleMemoryCache
  185. {
  186. public:
  187. public:
  188. uintptr mAddr;
  189. int mSize;
  190. int mBlockSize;
  191. uint8** mBlocks;
  192. DbgMemoryFlags* mFlags;
  193. int mBlockCount;
  194. bool mOwns;
  195. public:
  196. DbgModuleMemoryCache(uintptr addr, int size);
  197. //DbgModuleMemoryCache(uintptr addr, uint8* data, int size, bool makeCopy);
  198. ~DbgModuleMemoryCache();
  199. DbgMemoryFlags Read(uintptr addr, uint8* data, int size);
  200. void ReportMemory(MemReporter* memReporter);
  201. };
  202. class DbgHotResolveData
  203. {
  204. public:
  205. struct TypeData
  206. {
  207. intptr mCount;
  208. intptr mSize;
  209. TypeData()
  210. {
  211. mCount = 0;
  212. mSize = 0;
  213. }
  214. };
  215. public:
  216. Array<TypeData> mTypeData;
  217. Beefy::HashSet<String> mBeefCallStackEntries;
  218. };
  219. class Profiler;
  220. class Debugger
  221. {
  222. public:
  223. DebugManager* mDebugManager;
  224. RunState mRunState;
  225. DbgHotResolveData* mHotResolveData;
  226. bool mHadImageFindError;
  227. public:
  228. Debugger()
  229. {
  230. mDebugManager = NULL;
  231. mRunState = RunState_NotStarted;
  232. mHotResolveData = NULL;
  233. mHadImageFindError = false;
  234. }
  235. virtual ~Debugger() { delete mHotResolveData; }
  236. virtual void OutputMessage(const StringImpl& msg) = 0;
  237. virtual void OutputRawMessage(const StringImpl& msg) = 0;
  238. virtual int GetAddrSize() = 0;
  239. virtual bool CanOpen(const StringImpl& fileName, DebuggerResult* outResult) = 0;
  240. virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock, bool hotSwapEnabled, DbgOpenFileFlags openFileFlags) = 0;
  241. virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) = 0;
  242. virtual void GetStdHandles(BfpFile** outStdIn, BfpFile** outStdOut, BfpFile** outStdErr) = 0;
  243. virtual void Run() = 0;
  244. virtual bool HasLoadedTargetBinary() { return true; }
  245. virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) = 0;
  246. virtual void InitiateHotResolve(DbgHotResolveFlags flags) = 0;
  247. virtual intptr GetDbgAllocHeapSize() = 0;
  248. virtual String GetDbgAllocInfo() = 0;
  249. virtual void Update() = 0;
  250. virtual void ContinueDebugEvent() = 0;
  251. virtual void ForegroundTarget(int altProcessId) = 0;
  252. virtual Breakpoint* CreateBreakpoint(const StringImpl& fileName, int lineNum, int wantColumn, int instrOffset) = 0;
  253. virtual Breakpoint* CreateMemoryBreakpoint(intptr addr, int byteCount) = 0;
  254. virtual Breakpoint* CreateSymbolBreakpoint(const StringImpl& symbolName) = 0;
  255. virtual Breakpoint* CreateAddressBreakpoint(intptr address) = 0;
  256. virtual void CheckBreakpoint(Breakpoint* breakpoint) = 0;
  257. virtual void HotBindBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int hotIdx) = 0;
  258. virtual void DeleteBreakpoint(Breakpoint* wdBreakpoint) = 0;
  259. virtual void DetachBreakpoint(Breakpoint* wdBreakpoint) = 0;
  260. virtual void MoveBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int wantColumn, bool rebindNow) = 0;
  261. virtual void MoveMemoryBreakpoint(Breakpoint* wdBreakpoint, intptr addr, int byteCount) = 0;
  262. virtual void DisableBreakpoint(Breakpoint* wdBreakpoint) = 0;
  263. virtual void SetBreakpointCondition(Breakpoint* wdBreakpoint, const StringImpl& condition) = 0;
  264. virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) = 0;
  265. virtual Breakpoint* FindBreakpointAt(intptr address) = 0;
  266. virtual Breakpoint* GetActiveBreakpoint() = 0;
  267. virtual uintptr GetBreakpointAddr(Breakpoint* breakpoint) { return breakpoint->GetAddr(); }
  268. virtual void BreakAll() = 0;
  269. virtual bool TryRunContinue() = 0;
  270. virtual void StepInto(bool inAssembly) = 0;
  271. virtual void StepIntoSpecific(intptr addr) = 0;
  272. virtual void StepOver(bool inAssembly) = 0;
  273. virtual void StepOut(bool inAssembly) = 0;
  274. virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) = 0;
  275. //virtual DbgTypedValue GetRegister(const StringImpl& regName, CPURegisters* registers, Array<RegForm>* regForms = NULL) = 0;
  276. virtual String Evaluate(const StringImpl& expr, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) = 0;
  277. virtual String EvaluateContinue() = 0;
  278. virtual void EvaluateContinueKeep() = 0;
  279. virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) = 0;
  280. virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) = 0;
  281. virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) = 0;
  282. virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) = 0;
  283. virtual String GetAutoLocals(int callStackIdx, bool showRegs) = 0;
  284. virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) = 0;
  285. virtual String GetProcessInfo() = 0;
  286. virtual int GetProcessId() = 0;
  287. virtual String GetThreadInfo() = 0;
  288. virtual void SetActiveThread(int threadId) = 0;
  289. virtual int GetActiveThread() = 0;
  290. virtual void FreezeThread(int threadId) = 0;
  291. virtual void ThawThread(int threadId) = 0;
  292. virtual bool IsActiveThreadWaiting() = 0;
  293. virtual void ClearCallStack() = 0;
  294. virtual void UpdateCallStack(bool slowEarlyOut = true) = 0;
  295. virtual int GetCallStackCount() = 0;
  296. virtual int GetRequestedStackFrameIdx() = 0;
  297. virtual int GetBreakStackFrameIdx() = 0;
  298. virtual bool ReadMemory(intptr address, uint64 length, void* dest, bool local = false) = 0;
  299. virtual bool WriteMemory(intptr address, void* src, uint64 length) = 0;
  300. virtual DbgMemoryFlags GetMemoryFlags(intptr address) = 0;
  301. virtual void UpdateRegisterUsage(int stackFrameIdx) = 0;
  302. virtual void UpdateCallStackMethod(int stackFrameIdx) = 0;
  303. virtual void GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) = 0;
  304. virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) = 0;
  305. virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) = 0;
  306. virtual String GetStackFrameId(int stackFrameIdx) { return ""; }
  307. virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) = 0;
  308. virtual int GetJmpState(int stackFrameIdx) = 0;
  309. virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) = 0;
  310. virtual String GetStackMethodOwner(int stackFrameIdx, int& language) = 0;
  311. virtual String FindCodeAddresses(const StringImpl& fileName, int line, int column, bool allowAutoResolve) = 0;
  312. virtual String GetAddressSourceLocation(intptr address) = 0;
  313. virtual String GetAddressSymbolName(intptr address, bool demangle) = 0;
  314. virtual String DisassembleAtRaw(intptr address) = 0;
  315. virtual String DisassembleAt(intptr address) = 0;
  316. virtual String FindLineCallAddresses(intptr address) = 0;
  317. virtual String GetCurrentException() = 0;
  318. virtual String GetModulesInfo() = 0;
  319. virtual String GetModuleInfo(const StringImpl& moduleName) { return ""; }
  320. virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) = 0;
  321. virtual void CancelSymSrv() = 0;
  322. virtual bool HasPendingDebugLoads() = 0;
  323. virtual int LoadImageForModule(const StringImpl& moduleName, const StringImpl& debugFileName) = 0;
  324. virtual int LoadDebugInfoForModule(const StringImpl& moduleName) = 0;
  325. virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName) = 0;
  326. virtual void StopDebugging() = 0;
  327. virtual void Terminate() = 0;
  328. virtual void Detach() = 0;
  329. virtual Profiler* StartProfiling() = 0;
  330. virtual Profiler* PopProfiler() = 0; // Profiler requested by target program
  331. virtual void ReportMemory(MemReporter* memReporter) = 0;
  332. virtual bool IsOnDemandDebugger() = 0;
  333. virtual bool GetEmitSource(const StringImpl& filePath, String& outText) = 0;
  334. };
  335. class Profiler
  336. {
  337. public:
  338. String mDescription;
  339. int mSamplesPerSecond;
  340. intptr mTargetThreadId;
  341. public:
  342. Profiler()
  343. {
  344. mSamplesPerSecond = -1;
  345. mTargetThreadId = 0;
  346. }
  347. virtual ~Profiler() {}
  348. virtual void Start() = 0;
  349. virtual void Stop() = 0;
  350. virtual void Clear() = 0;
  351. virtual bool IsSampling() = 0;
  352. virtual String GetOverview() = 0;
  353. virtual String GetThreadList() = 0;
  354. virtual String GetCallTree(int threadId, bool reverse) = 0;
  355. };
  356. NS_BF_END