Debugger.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. struct Il2CppThreadUnwindState* unwindState;
  17. int32_t tryId;
  18. #ifdef __cplusplus
  19. Il2CppSequencePointExecutionContext(const MethodInfo* method, void** thisArg, void** params, void** locals);
  20. ~Il2CppSequencePointExecutionContext();
  21. #endif //__cplusplus
  22. } Il2CppSequencePointExecutionContext;
  23. typedef struct Il2CppThreadUnwindState
  24. {
  25. Il2CppSequencePointExecutionContext** executionContexts;
  26. uint32_t frameCount;
  27. uint32_t frameCapacity;
  28. } Il2CppThreadUnwindState;
  29. typedef int32_t (*Il2CppMonoInternalStackWalk) (void /*MonoStackFrameInfo*/ *frame, void /*MonoContext*/ *ctx, void* data);
  30. struct Il2CppMonoInterpCallbacks
  31. {
  32. void* (*create_method_pointer) (MethodInfo *method, void /*MonoError*/ *error);
  33. Il2CppObject* (*runtime_invoke) (MethodInfo *method, void *obj, void **params, Il2CppObject **exc, void /*MonoError*/ *error);
  34. void (*init_delegate) (Il2CppDelegate *del);
  35. #ifndef DISABLE_REMOTING
  36. void* (*get_remoting_invoke) (void* imethod, void /*MonoError*/ *error);
  37. #endif
  38. void* (*create_trampoline) (Il2CppDomain *domain, MethodInfo *method, void /*MonoError*/ *error);
  39. void (*walk_stack_with_ctx) (Il2CppMonoInternalStackWalk func, void /*MonoContext*/ *ctx, int32_t /*MonoUnwindOptions*/ options, void *user_data);
  40. void (*set_resume_state) (void /*MonoJitTlsData*/ *jit_tls, Il2CppException *ex, void /*MonoJitExceptionInfo*/ *ei, Il2CppSequencePointExecutionContext* interp_frame, void* handler_ip);
  41. int32_t (*run_finally) (void /*MonoStackFrameInfo*/ *frame, int clause_index, void* handler_ip);
  42. int32_t (*run_filter) (void /*MonoStackFrameInfo*/ *frame, Il2CppException *ex, int clause_index, void* handler_ip);
  43. void (*frame_iter_init) (void /*MonoInterpStackIter*/ *iter, void* interp_exit_data);
  44. int32_t (*frame_iter_next) (void /*MonoInterpStackIter*/ *iter, void /*MonoStackFrameInfo*/ *frame);
  45. void* /*MonoJitInfo*/ (*find_jit_info) (Il2CppDomain *domain, MethodInfo *method);
  46. void (*set_breakpoint) (void /*MonoJitInfo*/ *jinfo, void* ip);
  47. void (*clear_breakpoint) (void /*MonoJitInfo*/ *jinfo, void* ip);
  48. void* /*MonoJitInfo*/ (*frame_get_jit_info) (Il2CppSequencePointExecutionContext* frame);
  49. void* (*frame_get_ip) (Il2CppSequencePointExecutionContext* frame);
  50. void* (*frame_get_arg) (Il2CppSequencePointExecutionContext* frame, int pos);
  51. void* (*frame_get_local) (Il2CppSequencePointExecutionContext* frame, int pos);
  52. void* (*frame_get_this) (Il2CppSequencePointExecutionContext* frame);
  53. Il2CppSequencePointExecutionContext* (*frame_get_parent) (Il2CppSequencePointExecutionContext* frame);
  54. void (*start_single_stepping) ();
  55. void (*stop_single_stepping) ();
  56. };
  57. #ifdef __cplusplus
  58. extern "C"
  59. {
  60. int32_t unity_sequence_point_active_entry(Il2CppSequencePoint *seqPoint);
  61. int32_t unity_sequence_point_active_exit(Il2CppSequencePoint *seqPoint);
  62. extern int32_t g_unity_pause_point_active;
  63. }
  64. #include <stdint.h>
  65. #include "os/Atomic.h"
  66. #include "os/ThreadLocalValue.h"
  67. #undef IsLoggingEnabled
  68. extern il2cpp::os::ThreadLocalValue s_ExecutionContexts;
  69. namespace il2cpp
  70. {
  71. namespace os
  72. {
  73. class Thread;
  74. }
  75. namespace utils
  76. {
  77. class Debugger
  78. {
  79. public:
  80. static void RegisterMetadata(const Il2CppDebuggerMetadataRegistration *data);
  81. static void SetAgentOptions(const char* options);
  82. static void RegisterTransport(const Il2CppDebuggerTransport* transport);
  83. static void Init();
  84. static void Start();
  85. static void StartDebuggerThread();
  86. static inline Il2CppThreadUnwindState* PushExecutionContext(Il2CppSequencePointExecutionContext* executionContext)
  87. {
  88. Il2CppThreadUnwindState* unwindState;
  89. s_ExecutionContexts.GetValue(reinterpret_cast<void**>(&unwindState));
  90. if (unwindState->frameCount == unwindState->frameCapacity)
  91. GrowFrameCapacity(unwindState);
  92. unwindState->executionContexts[unwindState->frameCount] = executionContext;
  93. unwindState->frameCount++;
  94. return unwindState;
  95. }
  96. static inline void PopExecutionContext(Il2CppThreadUnwindState* unwindState)
  97. {
  98. IL2CPP_ASSERT(unwindState->frameCount > 0);
  99. unwindState->frameCount--;
  100. }
  101. typedef void(*OnBreakPointHitCallback) (Il2CppSequencePoint* sequencePoint);
  102. typedef void (*OnPausePointHitCallback) ();
  103. static void RegisterCallbacks(OnBreakPointHitCallback breakCallback, OnPausePointHitCallback pauseCallback);
  104. static Il2CppThreadUnwindState* GetThreadStatePointer();
  105. static void SaveThreadContext(Il2CppThreadUnwindState* context, int frameCountAdjust);
  106. static void FreeThreadContext(Il2CppThreadUnwindState* context);
  107. static void OnBreakPointHit(Il2CppSequencePoint *sequencePoint);
  108. static void OnPausePointHit();
  109. static bool IsGlobalBreakpointActive();
  110. static bool GetIsDebuggerAttached();
  111. static void SetIsDebuggerAttached(bool attached);
  112. static bool IsDebuggerThread(os::Thread* thread);
  113. static void AllocateThreadLocalData();
  114. static void FreeThreadLocalData();
  115. static Il2CppSequencePoint* GetSequencePoint(const Il2CppImage* image, size_t id);
  116. static Il2CppSequencePoint* GetSequencePoints(const MethodInfo* method, void**iter);
  117. static Il2CppSequencePoint* GetSequencePoint(const Il2CppImage* image, Il2CppCatchPoint* cp);
  118. static Il2CppCatchPoint* GetCatchPoints(const MethodInfo* method, void**iter);
  119. static Il2CppSequencePoint* GetAllSequencePoints(void* *iter);
  120. static void HandleException(Il2CppException *exc);
  121. static const char** GetTypeSourceFiles(const Il2CppClass *klass, int& count);
  122. static void UserBreak();
  123. static bool IsLoggingEnabled();
  124. static void Log(int level, Il2CppString *category, Il2CppString *message);
  125. static inline bool IsSequencePointActive(Il2CppSequencePoint *seqPoint)
  126. {
  127. return il2cpp::os::Atomic::LoadRelaxed(&seqPoint->isActive) || g_unity_pause_point_active;
  128. }
  129. static inline bool IsSequencePointActiveEntry(Il2CppSequencePoint *seqPoint)
  130. {
  131. return unity_sequence_point_active_entry(seqPoint);
  132. }
  133. static inline bool IsSequencePointActiveExit(Il2CppSequencePoint *seqPoint)
  134. {
  135. return unity_sequence_point_active_exit(seqPoint);
  136. }
  137. static bool IsPausePointActive();
  138. static const MethodInfo* GetSequencePointMethod(const Il2CppImage* image, Il2CppSequencePoint *seqPoint);
  139. static const MethodInfo* GetCatchPointMethod(const Il2CppImage* image, Il2CppCatchPoint *catchPoint);
  140. static inline void CheckSequencePoint(Il2CppSequencePointExecutionContext* executionContext, Il2CppSequencePoint* seqPoint)
  141. {
  142. if (IsSequencePointActive(seqPoint))
  143. {
  144. executionContext->currentSequencePoint = seqPoint;
  145. OnBreakPointHit(seqPoint);
  146. }
  147. }
  148. static inline void CheckSequencePointEntry(Il2CppSequencePointExecutionContext* executionContext, Il2CppSequencePoint* seqPoint)
  149. {
  150. if (IsSequencePointActiveEntry(seqPoint))
  151. {
  152. executionContext->currentSequencePoint = seqPoint;
  153. OnBreakPointHit(seqPoint);
  154. }
  155. }
  156. static inline void CheckSequencePointExit(Il2CppSequencePointExecutionContext* executionContext, Il2CppSequencePoint* seqPoint)
  157. {
  158. if (IsSequencePointActiveExit(seqPoint))
  159. {
  160. executionContext->currentSequencePoint = seqPoint;
  161. OnBreakPointHit(seqPoint);
  162. }
  163. }
  164. static void CheckPausePoint();
  165. static const char* GetLocalName(const MethodInfo* method, int32_t index);
  166. static const Il2CppMethodScope* GetLocalScope(const MethodInfo* method, int32_t index);
  167. static void GetMethodExecutionContextInfo(const MethodInfo* method, uint32_t* executionContextInfoCount, const Il2CppMethodExecutionContextInfo **executionContextInfo, const Il2CppMethodHeaderInfo **headerInfo, const Il2CppMethodScope **scopes);
  168. // The context parameter here is really il2cpp::vm::StackFrames*. We don't want to include vm/StackTrace.h in this file,
  169. // as this one is included in generated code.
  170. static void GetStackFrames(void* context);
  171. static void AcquireLoaderLock();
  172. static void ReleaseLoaderLock();
  173. static bool LoaderLockIsOwnedByThisThread();
  174. static Il2CppMonoInterpCallbacks* GetInterpCallbacks();
  175. static void RuntimeShutdownEnd();
  176. static void ThreadStarted(uintptr_t tid);
  177. static void ThreadStopped(uintptr_t tid);
  178. private:
  179. static os::ThreadLocalValue s_IsGlobalBreakpointActive;
  180. static void InitializeMethodToSequencePointMap();
  181. static void InitializeTypeSourceFileMap();
  182. static void InitializeMethodToCatchPointMap();
  183. static void GrowFrameCapacity(Il2CppThreadUnwindState* unwindState);
  184. };
  185. }
  186. }
  187. inline Il2CppSequencePointExecutionContext::Il2CppSequencePointExecutionContext(const MethodInfo* method, void** thisArg, void** params, void** locals)
  188. : method(method),
  189. thisArg(thisArg),
  190. params(params),
  191. locals(locals),
  192. currentSequencePoint(NULL),
  193. tryId(-1)
  194. {
  195. unwindState = il2cpp::utils::Debugger::PushExecutionContext(this);
  196. }
  197. inline Il2CppSequencePointExecutionContext::~Il2CppSequencePointExecutionContext()
  198. {
  199. il2cpp::utils::Debugger::PopExecutionContext(unwindState);
  200. // il2cpp_save_current_thread_context_func_exit();
  201. }
  202. #endif //__cplusplus