Revert "[mono][debugger] First PR to implement iCorDebug on mono (#20757)"
[mono-project.git] / mono / mini / debugger-engine.h
blobfa8dd2792f00a0536f66bca71d5e6dc7141d7887
1 /**
2 * \file
3 */
5 #ifndef __MONO_DEBUGGER_ENGINE_H__
6 #define __MONO_DEBUGGER_ENGINE_H__
8 #include "mini.h"
9 #include <mono/metadata/seq-points-data.h>
10 #include <mono/mini/debugger-state-machine.h>
11 #include <mono/metadata/mono-debug.h>
12 #include <mono/mini/interp/interp-internals.h>
15 FIXME:
16 - Move EventKind back to debugger-agent.c as it contains sdb wire protocol constants.
17 This is complicated because EventRequest has an event_kind field.
21 typedef enum {
22 EVENT_KIND_VM_START = 0,
23 EVENT_KIND_VM_DEATH = 1,
24 EVENT_KIND_THREAD_START = 2,
25 EVENT_KIND_THREAD_DEATH = 3,
26 EVENT_KIND_APPDOMAIN_CREATE = 4,
27 EVENT_KIND_APPDOMAIN_UNLOAD = 5,
28 EVENT_KIND_METHOD_ENTRY = 6,
29 EVENT_KIND_METHOD_EXIT = 7,
30 EVENT_KIND_ASSEMBLY_LOAD = 8,
31 EVENT_KIND_ASSEMBLY_UNLOAD = 9,
32 EVENT_KIND_BREAKPOINT = 10,
33 EVENT_KIND_STEP = 11,
34 EVENT_KIND_TYPE_LOAD = 12,
35 EVENT_KIND_EXCEPTION = 13,
36 EVENT_KIND_KEEPALIVE = 14,
37 EVENT_KIND_USER_BREAK = 15,
38 EVENT_KIND_USER_LOG = 16,
39 EVENT_KIND_CRASH = 17
40 } EventKind;
42 typedef enum {
43 MOD_KIND_COUNT = 1,
44 MOD_KIND_THREAD_ONLY = 3,
45 MOD_KIND_LOCATION_ONLY = 7,
46 MOD_KIND_EXCEPTION_ONLY = 8,
47 MOD_KIND_STEP = 10,
48 MOD_KIND_ASSEMBLY_ONLY = 11,
49 MOD_KIND_SOURCE_FILE_ONLY = 12,
50 MOD_KIND_TYPE_NAME_ONLY = 13,
51 MOD_KIND_NONE = 14
52 } ModifierKind;
54 typedef enum {
55 STEP_DEPTH_INTO = 0,
56 STEP_DEPTH_OVER = 1,
57 STEP_DEPTH_OUT = 2
58 } StepDepth;
60 typedef enum {
61 STEP_SIZE_MIN = 0,
62 STEP_SIZE_LINE = 1
63 } StepSize;
65 typedef enum {
66 STEP_FILTER_NONE = 0,
67 STEP_FILTER_STATIC_CTOR = 1,
68 STEP_FILTER_DEBUGGER_HIDDEN = 2,
69 STEP_FILTER_DEBUGGER_STEP_THROUGH = 4,
70 STEP_FILTER_DEBUGGER_NON_USER_CODE = 8
71 } StepFilter;
73 typedef struct {
74 ModifierKind kind;
75 union {
76 int count; /* For kind == MOD_KIND_COUNT */
77 MonoInternalThread *thread; /* For kind == MOD_KIND_THREAD_ONLY */
78 MonoClass *exc_class; /* For kind == MONO_KIND_EXCEPTION_ONLY */
79 MonoAssembly **assemblies; /* For kind == MONO_KIND_ASSEMBLY_ONLY */
80 GHashTable *source_files; /* For kind == MONO_KIND_SOURCE_FILE_ONLY */
81 GHashTable *type_names; /* For kind == MONO_KIND_TYPE_NAME_ONLY */
82 StepFilter filter; /* For kind == MOD_KIND_STEP */
83 } data;
84 gboolean caught, uncaught, subclasses, not_filtered_feature, everything_else; /* For kind == MOD_KIND_EXCEPTION_ONLY */
85 } Modifier;
87 typedef struct{
88 int id;
89 int event_kind;
90 int suspend_policy;
91 int nmodifiers;
92 gpointer info;
93 Modifier modifiers [MONO_ZERO_LEN_ARRAY];
94 } EventRequest;
97 * Describes a single step request.
99 typedef struct {
100 EventRequest *req;
101 MonoInternalThread *thread;
102 StepDepth depth;
103 StepSize size;
104 StepFilter filter;
105 gpointer last_sp;
106 gpointer start_sp;
107 MonoMethod *start_method;
108 MonoMethod *last_method;
109 int last_line;
110 /* Whenever single stepping is performed using start/stop_single_stepping () */
111 gboolean global;
112 /* The list of breakpoints used to implement step-over */
113 GSList *bps;
114 /* The number of frames at the start of a step-over */
115 int nframes;
116 /* If set, don't stop in methods that are not part of user assemblies */
117 MonoAssembly** user_assemblies;
118 /* Used to distinguish stepping breakpoint hits in parallel tasks executions */
119 int async_id;
120 /* Used to know if we are in process of async step-out and distishing from exception breakpoints */
121 MonoMethod* async_stepout_method;
122 int refcount;
123 } SingleStepReq;
127 * Contains information about an inserted breakpoint.
129 typedef struct {
130 long il_offset, native_offset;
131 guint8 *ip;
132 MonoJitInfo *ji;
133 MonoDomain *domain;
134 } BreakpointInstance;
137 * Contains generic information about a breakpoint.
139 typedef struct {
141 * The method where the breakpoint is placed. Can be NULL in which case it
142 * is inserted into every method. This is used to implement method entry/
143 * exit events. Can be a generic method definition, in which case the
144 * breakpoint is inserted into every instance.
146 MonoMethod *method;
147 long il_offset;
148 EventRequest *req;
150 * A list of BreakpointInstance structures describing where the breakpoint
151 * was inserted. There could be more than one because of
152 * generics/appdomains/method entry/exit.
154 GPtrArray *children;
155 } MonoBreakpoint;
157 typedef struct {
158 MonoJitInfo *ji;
159 MonoDomain *domain;
160 MonoMethod *method;
161 guint32 native_offset;
162 } DbgEngineStackFrame;
164 typedef struct {
166 * Method where to start single stepping
168 MonoMethod *method;
171 * If ctx is set, tls must belong to the same thread.
173 MonoContext *ctx;
174 void *tls;
177 * Stopped at a throw site
179 gboolean step_to_catch;
182 * Sequence point to start from.
184 SeqPoint sp;
185 MonoSeqPointInfo *info;
188 * Frame data, will be freed at the end of ss_start if provided
190 DbgEngineStackFrame **frames;
191 int nframes;
192 } SingleStepArgs;
195 * OBJECT IDS
199 * Represents an object accessible by the debugger client.
201 typedef struct {
202 /* Unique id used in the wire protocol to refer to objects */
203 int id;
205 * A weakref gc handle pointing to the object. The gc handle is used to
206 * detect if the object was garbage collected.
208 MonoGCHandle handle;
209 } ObjRef;
211 typedef struct
213 //Must be the first field to ensure pointer equivalence
214 DbgEngineStackFrame de;
215 int id;
216 guint32 il_offset;
218 * If method is gshared, this is the actual instance, otherwise this is equal to
219 * method.
221 MonoMethod *actual_method;
223 * This is the method which is visible to debugger clients. Same as method,
224 * except for native-to-managed wrappers.
226 MonoMethod *api_method;
227 MonoContext ctx;
228 MonoDebugMethodJitInfo *jit;
229 MonoInterpFrameHandle interp_frame;
230 gpointer frame_addr;
231 int flags;
232 host_mgreg_t *reg_locations [MONO_MAX_IREGS];
234 * Whenever ctx is set. This is FALSE for the last frame of running threads, since
235 * the frame can become invalid.
237 gboolean has_ctx;
238 } StackFrame;
240 void mono_debugger_free_objref (gpointer value);
242 typedef int DbgEngineErrorCode;
243 #define DE_ERR_NONE 0
244 // WARNING WARNING WARNING
245 // Error codes MUST match those of sdb for now
246 #define DE_ERR_NOT_IMPLEMENTED 100
248 MonoGHashTable *
249 mono_debugger_get_thread_states (void);
251 gboolean
252 mono_debugger_is_disconnected (void);
254 gsize
255 mono_debugger_tls_thread_id (DebuggerTlsData *debuggerTlsData);
257 void
258 mono_debugger_set_thread_state (DebuggerTlsData *ref, MonoDebuggerThreadState expected, MonoDebuggerThreadState set);
260 MonoDebuggerThreadState
261 mono_debugger_get_thread_state (DebuggerTlsData *ref);
263 typedef struct {
264 MonoContext *(*tls_get_restore_state) (void *tls);
265 gboolean (*try_process_suspend) (void *tls, MonoContext *ctx, gboolean from_breakpoint);
266 gboolean (*begin_breakpoint_processing) (void *tls, MonoContext *ctx, MonoJitInfo *ji, gboolean from_signal);
267 void (*begin_single_step_processing) (MonoContext *ctx, gboolean from_signal);
269 void (*ss_discard_frame_context) (void *tls);
270 void (*ss_calculate_framecount) (void *tls, MonoContext *ctx, gboolean force_use_ctx, DbgEngineStackFrame ***frames, int *nframes);
271 gboolean (*ensure_jit) (DbgEngineStackFrame *frame);
272 int (*ensure_runtime_is_suspended) (void);
274 int (*get_this_async_id) (DbgEngineStackFrame *frame);
276 void* (*create_breakpoint_events) (GPtrArray *ss_reqs, GPtrArray *bp_reqs, MonoJitInfo *ji, EventKind kind);
277 void (*process_breakpoint_events) (void *_evts, MonoMethod *method, MonoContext *ctx, int il_offset);
279 gboolean (*set_set_notification_for_wait_completion_flag) (DbgEngineStackFrame *f);
280 MonoMethod* (*get_notify_debugger_of_wait_completion_method)(void);
282 int (*ss_create_init_args) (SingleStepReq *ss_req, SingleStepArgs *args);
283 void (*ss_args_destroy) (SingleStepArgs *ss_args);
284 int (*handle_multiple_ss_requests)(void);
285 } DebuggerEngineCallbacks;
288 void mono_de_init (DebuggerEngineCallbacks *cbs);
289 void mono_de_cleanup (void);
290 void mono_de_set_log_level (int level, FILE *file);
292 //locking - we expose the lock object from the debugging engine to ensure we keep the same locking semantics of sdb.
293 void mono_de_lock (void);
294 void mono_de_unlock (void);
296 // domain handling
297 void mono_de_foreach_domain (GHFunc func, gpointer user_data);
298 void mono_de_domain_add (MonoDomain *domain);
299 void mono_de_domain_remove (MonoDomain *domain);
301 //breakpoints
302 void mono_de_clear_breakpoint (MonoBreakpoint *bp);
303 MonoBreakpoint* mono_de_set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req, MonoError *error);
304 void mono_de_collect_breakpoints_by_sp (SeqPoint *sp, MonoJitInfo *ji, GPtrArray *ss_reqs, GPtrArray *bp_reqs);
305 void mono_de_clear_breakpoints_for_domain (MonoDomain *domain);
306 void mono_de_add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji);
307 void mono_de_clear_all_breakpoints (void);
308 MonoBreakpoint * mono_de_get_breakpoint_by_id (int id);
310 //single stepping
311 void mono_de_start_single_stepping (void);
312 void mono_de_stop_single_stepping (void);
314 void mono_de_process_breakpoint (void *tls, gboolean from_signal);
315 void mono_de_process_single_step (void *tls, gboolean from_signal);
316 DbgEngineErrorCode mono_de_ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilter filter, EventRequest *req);
317 void mono_de_cancel_ss (SingleStepReq *req);
318 void mono_de_cancel_all_ss (void);
320 gboolean set_set_notification_for_wait_completion_flag (DbgEngineStackFrame *frame);
321 MonoClass * get_class_to_get_builder_field(DbgEngineStackFrame *frame);
322 gpointer get_this_addr (DbgEngineStackFrame *the_frame);
323 gpointer get_async_method_builder (DbgEngineStackFrame *frame);
324 MonoMethod* get_set_notification_method (MonoClass* async_builder_class);
325 MonoMethod* get_notify_debugger_of_wait_completion_method (void);
326 MonoMethod* get_object_id_for_debugger_method (MonoClass* async_builder_class);
328 #ifdef HOST_ANDROID
329 #define PRINT_DEBUG_MSG(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { g_print (__VA_ARGS__); } } while (0)
330 #define DEBUG(level,s) do { if (G_UNLIKELY ((level) <= log_level)) { s; } } while (0)
331 #elif HOST_WASM
332 void wasm_debugger_log(int level, const gchar *format, ...);
333 #define PRINT_DEBUG_MSG(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { wasm_debugger_log (level, __VA_ARGS__); } } while (0)
334 #define DEBUG(level,s) do { if (G_UNLIKELY ((level) <= log_level)) { s; } } while (0)
335 #elif defined(HOST_WIN32) && !HAVE_API_SUPPORT_WIN32_CONSOLE
336 void win32_debugger_log(FILE *stream, const gchar *format, ...);
337 #define PRINT_DEBUG_MSG(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { win32_debugger_log (log_file, __VA_ARGS__); } } while (0)
338 #define DEBUG(level,s) do { if (G_UNLIKELY ((level) <= log_level)) { s; } } while (0)
339 #else
340 #define PRINT_DEBUG_MSG(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { fprintf (log_file, __VA_ARGS__); fflush (log_file); } } while (0)
341 #define DEBUG(level,s) do { if (G_UNLIKELY ((level) <= log_level)) { s; fflush (log_file); } } while (0)
342 #endif
343 #endif
345 #if defined(HOST_WIN32) && !HAVE_API_SUPPORT_WIN32_CONSOLE
346 void win32_debugger_log(FILE *stream, const gchar *format, ...);
347 #define PRINT_ERROR_MSG(...) win32_debugger_log (log_file, __VA_ARGS__)
348 #define PRINT_MSG(...) win32_debugger_log (log_file, __VA_ARGS__)
349 #else
350 #define PRINT_ERROR_MSG(...) g_printerr (__VA_ARGS__)
351 #define PRINT_MSG(...) g_print (__VA_ARGS__)
352 #endif