5 #ifndef __MONO_DEBUGGER_ENGINE_H__
6 #define __MONO_DEBUGGER_ENGINE_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>
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.
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,
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,
44 MOD_KIND_THREAD_ONLY
= 3,
45 MOD_KIND_LOCATION_ONLY
= 7,
46 MOD_KIND_EXCEPTION_ONLY
= 8,
48 MOD_KIND_ASSEMBLY_ONLY
= 11,
49 MOD_KIND_SOURCE_FILE_ONLY
= 12,
50 MOD_KIND_TYPE_NAME_ONLY
= 13,
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
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 */
84 gboolean caught
, uncaught
, subclasses
, not_filtered_feature
, everything_else
; /* For kind == MOD_KIND_EXCEPTION_ONLY */
93 Modifier modifiers
[MONO_ZERO_LEN_ARRAY
];
97 * Describes a single step request.
101 MonoInternalThread
*thread
;
107 MonoMethod
*start_method
;
108 MonoMethod
*last_method
;
110 /* Whenever single stepping is performed using start/stop_single_stepping () */
112 /* The list of breakpoints used to implement step-over */
114 /* The number of frames at the start of a step-over */
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 */
120 /* Used to know if we are in process of async step-out and distishing from exception breakpoints */
121 MonoMethod
* async_stepout_method
;
127 * Contains information about an inserted breakpoint.
130 long il_offset
, native_offset
;
134 } BreakpointInstance
;
137 * Contains generic information about a breakpoint.
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.
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.
161 guint32 native_offset
;
162 } DbgEngineStackFrame
;
166 * Method where to start single stepping
171 * If ctx is set, tls must belong to the same thread.
177 * Stopped at a throw site
179 gboolean step_to_catch
;
182 * Sequence point to start from.
185 MonoSeqPointInfo
*info
;
188 * Frame data, will be freed at the end of ss_start if provided
190 DbgEngineStackFrame
**frames
;
199 * Represents an object accessible by the debugger client.
202 /* Unique id used in the wire protocol to refer to objects */
205 * A weakref gc handle pointing to the object. The gc handle is used to
206 * detect if the object was garbage collected.
213 //Must be the first field to ensure pointer equivalence
214 DbgEngineStackFrame de
;
218 * If method is gshared, this is the actual instance, otherwise this is equal to
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
;
228 MonoDebugMethodJitInfo
*jit
;
229 MonoInterpFrameHandle interp_frame
;
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.
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
249 mono_debugger_get_thread_states (void);
252 mono_debugger_is_disconnected (void);
255 mono_debugger_tls_thread_id (DebuggerTlsData
*debuggerTlsData
);
258 mono_debugger_set_thread_state (DebuggerTlsData
*ref
, MonoDebuggerThreadState expected
, MonoDebuggerThreadState set
);
260 MonoDebuggerThreadState
261 mono_debugger_get_thread_state (DebuggerTlsData
*ref
);
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);
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
);
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
);
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
);
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)
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)
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)
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__)
350 #define PRINT_ERROR_MSG(...) g_printerr (__VA_ARGS__)
351 #define PRINT_MSG(...) g_print (__VA_ARGS__)