Debugger.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #pragma once
  2. #include "il2cpp-class-internals.h"
  3. struct Il2CppSequencePoint;
  4. struct Il2CppCatchPoint;
  5. struct Il2CppSequencePointExecutionContext;
  6. struct Il2CppThreadUnwindState;
  7. typedef void(*DebugInfoInitialization)();
  8. typedef void(*ThreadCallback)(void*, uintptr_t);
  9. typedef struct Il2CppSequencePointExecutionContext
  10. {
  11. const MethodInfo* method;
  12. void** thisArg;
  13. void** params;
  14. void** locals;
  15. Il2CppSequencePoint* currentSequencePoint;
  16. int32_t tryId;
  17. #ifdef __cplusplus
  18. Il2CppSequencePointExecutionContext(const MethodInfo* method, void** thisArg, void** params, void** locals);
  19. ~Il2CppSequencePointExecutionContext();
  20. #endif //__cplusplus
  21. } Il2CppSequencePointExecutionContext;
  22. typedef struct Il2CppThreadUnwindState
  23. {
  24. Il2CppSequencePointExecutionContext** executionContexts;
  25. uint32_t frameCount;
  26. uint32_t frameCapacity;
  27. } Il2CppThreadUnwindState;
  28. #ifdef __cplusplus
  29. extern "C"
  30. {
  31. int32_t unity_sequence_point_active_entry(Il2CppSequencePoint *seqPoint);
  32. int32_t unity_sequence_point_active_exit(Il2CppSequencePoint *seqPoint);
  33. extern int32_t g_unity_pause_point_active;
  34. }
  35. #include <stdint.h>
  36. #include "os/Atomic.h"
  37. #include "os/ThreadLocalValue.h"
  38. #undef IsLoggingEnabled
  39. extern il2cpp::os::ThreadLocalValue s_ExecutionContexts;
  40. namespace il2cpp
  41. {
  42. namespace os
  43. {
  44. class Thread;
  45. }
  46. namespace utils
  47. {
  48. class Debugger
  49. {
  50. public:
  51. static void RegisterMetadata(const Il2CppDebuggerMetadataRegistration *data);
  52. static void SetAgentOptions(const char* options);
  53. static void RegisterTransport(const Il2CppDebuggerTransport* transport);
  54. static void Init();
  55. static void Start();
  56. static void StartDebuggerThread();
  57. static inline void PushExecutionContext(Il2CppSequencePointExecutionContext* executionContext)
  58. {
  59. Il2CppThreadUnwindState* unwindState;
  60. s_ExecutionContexts.GetValue(reinterpret_cast<void**>(&unwindState));
  61. if (unwindState->frameCount == unwindState->frameCapacity)
  62. {
  63. IL2CPP_ASSERT(0);
  64. }
  65. unwindState->executionContexts[unwindState->frameCount] = executionContext;
  66. unwindState->frameCount++;
  67. }
  68. static inline void PopExecutionContext()
  69. {
  70. Il2CppThreadUnwindState* unwindState;
  71. s_ExecutionContexts.GetValue(reinterpret_cast<void**>(&unwindState));
  72. IL2CPP_ASSERT(unwindState->frameCount > 0);
  73. unwindState->frameCount--;
  74. }
  75. typedef void(*OnBreakPointHitCallback) (Il2CppSequencePoint* sequencePoint);
  76. typedef void (*OnPausePointHitCallback) ();
  77. static void RegisterCallbacks(OnBreakPointHitCallback breakCallback, OnPausePointHitCallback pauseCallback);
  78. static Il2CppThreadUnwindState* GetThreadStatePointer();
  79. static void SaveThreadContext(Il2CppThreadUnwindState* context, int frameCountAdjust);
  80. static void FreeThreadContext(Il2CppThreadUnwindState* context);
  81. static void OnBreakPointHit(Il2CppSequencePoint *sequencePoint);
  82. static void OnPausePointHit();
  83. static bool IsGlobalBreakpointActive();
  84. static bool GetIsDebuggerAttached();
  85. static void SetIsDebuggerAttached(bool attached);
  86. static bool IsDebuggerThread(os::Thread* thread);
  87. static void AllocateThreadLocalData();
  88. static void FreeThreadLocalData();
  89. static Il2CppSequencePoint* GetSequencePoint(const Il2CppImage* image, size_t id);
  90. static Il2CppSequencePoint* GetSequencePoints(const MethodInfo* method, void**iter);
  91. static Il2CppSequencePoint* GetSequencePoint(const Il2CppImage* image, Il2CppCatchPoint* cp);
  92. static Il2CppCatchPoint* GetCatchPoints(const MethodInfo* method, void**iter);
  93. static Il2CppSequencePoint* GetAllSequencePoints(void* *iter);
  94. static void HandleException(Il2CppException *exc);
  95. static const char** GetTypeSourceFiles(const Il2CppClass *klass, int& count);
  96. static void UserBreak();
  97. static bool IsLoggingEnabled();
  98. static void Log(int level, Il2CppString *category, Il2CppString *message);
  99. static inline bool AtomicReadIsActive(Il2CppSequencePoint *seqPoint)
  100. {
  101. return il2cpp::os::Atomic::CompareExchange(&seqPoint->isActive, seqPoint->isActive, -1) > 0;
  102. }
  103. static inline bool IsSequencePointActive(Il2CppSequencePoint *seqPoint)
  104. {
  105. return AtomicReadIsActive(seqPoint) || g_unity_pause_point_active;
  106. }
  107. static inline bool IsSequencePointActiveEntry(Il2CppSequencePoint *seqPoint)
  108. {
  109. return unity_sequence_point_active_entry(seqPoint);
  110. }
  111. static inline bool IsSequencePointActiveExit(Il2CppSequencePoint *seqPoint)
  112. {
  113. return unity_sequence_point_active_exit(seqPoint);
  114. }
  115. static bool IsPausePointActive();
  116. static const MethodInfo* GetSequencePointMethod(const Il2CppImage* image, Il2CppSequencePoint *seqPoint);
  117. static const MethodInfo* GetCatchPointMethod(const Il2CppImage* image, Il2CppCatchPoint *catchPoint);
  118. static inline void CheckSequencePoint(Il2CppSequencePointExecutionContext* executionContext, Il2CppSequencePoint* seqPoint)
  119. {
  120. if (IsSequencePointActive(seqPoint))
  121. {
  122. executionContext->currentSequencePoint = seqPoint;
  123. OnBreakPointHit(seqPoint);
  124. }
  125. }
  126. static inline void CheckSequencePointEntry(Il2CppSequencePointExecutionContext* executionContext, Il2CppSequencePoint* seqPoint)
  127. {
  128. if (IsSequencePointActiveEntry(seqPoint))
  129. {
  130. executionContext->currentSequencePoint = seqPoint;
  131. OnBreakPointHit(seqPoint);
  132. }
  133. }
  134. static inline void CheckSequencePointExit(Il2CppSequencePointExecutionContext* executionContext, Il2CppSequencePoint* seqPoint)
  135. {
  136. if (IsSequencePointActiveExit(seqPoint))
  137. {
  138. executionContext->currentSequencePoint = seqPoint;
  139. OnBreakPointHit(seqPoint);
  140. }
  141. }
  142. static void CheckPausePoint();
  143. static const char* GetLocalName(const MethodInfo* method, int32_t index);
  144. static const Il2CppMethodScope* GetLocalScope(const MethodInfo* method, int32_t index);
  145. static void GetMethodExecutionContextInfo(const MethodInfo* method, uint32_t* executionContextInfoCount, const Il2CppMethodExecutionContextInfo **executionContextInfo, const Il2CppMethodHeaderInfo **headerInfo, const Il2CppMethodScope **scopes);
  146. // The context parameter here is really il2cpp::vm::StackFrames*. We don't want to include vm/StackTrace.h in this file,
  147. // as this one is included in generated code.
  148. static void GetStackFrames(void* context);
  149. private:
  150. static os::ThreadLocalValue s_IsGlobalBreakpointActive;
  151. static void InitializeMethodToSequencePointMap();
  152. static void InitializeTypeSourceFileMap();
  153. static void InitializeMethodToCatchPointMap();
  154. };
  155. }
  156. }
  157. inline Il2CppSequencePointExecutionContext::Il2CppSequencePointExecutionContext(const MethodInfo* method, void** thisArg, void** params, void** locals)
  158. : method(method),
  159. thisArg(thisArg),
  160. params(params),
  161. locals(locals),
  162. currentSequencePoint(NULL),
  163. tryId(-1)
  164. {
  165. il2cpp::utils::Debugger::PushExecutionContext(this);
  166. }
  167. inline Il2CppSequencePointExecutionContext::~Il2CppSequencePointExecutionContext()
  168. {
  169. il2cpp::utils::Debugger::PopExecutionContext();
  170. // il2cpp_save_current_thread_context_func_exit();
  171. }
  172. #endif //__cplusplus