MonoMethodDesc *desc;
} MiniDebugBreakpointInfo;
-typedef struct
-{
- guint64 index;
- MonoMethod *method;
- MonoDebugMethodAddressList *address_list;
-} MiniDebugMethodBreakpointInfo;
-
typedef struct
{
MonoDebugMethodJitInfo *jit;
guint64 lmf_addr;
guint64 end_stack;
+ guint64 extended_notifications;
+
/* Next pointer. */
MonoDebuggerThreadInfo *next;
* The debugger doesn't access anything beyond this point.
*/
MonoJitTlsData *jit_tls;
+ MonoThread *thread;
};
MonoDebuggerThreadInfo *mono_debugger_thread_table = NULL;
-static void
-mono_debugger_check_breakpoints (MonoMethod *method, MonoDebugMethodAddress *debug_info);
-
static inline void
record_line_number (MiniDebugMethodInfo *info, guint32 address, guint32 offset)
{
g_array_append_val (info->line_numbers, lne);
}
-static void
-mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
-{
- g_free (jit->line_numbers);
- g_free (jit->this_var);
- g_free (jit->params);
- g_free (jit->locals);
- g_free (jit);
-}
void
mono_debug_init_method (MonoCompile *cfg, MonoBasicBlock *start_block, guint32 breakpoint_id)
static void
write_variable (MonoInst *inst, MonoDebugVarInfo *var)
{
+ var->type = inst->inst_vtype;
+
if (inst->opcode == OP_REGVAR)
var->index = inst->dreg | MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER;
else {
jit->epilogue_begin = cfg->epilog_begin;
jit->code_size = cfg->code_len;
- record_line_number (info, jit->epilogue_begin, header->code_size);
+ if (jit->epilogue_begin)
+ record_line_number (info, jit->epilogue_begin, header->code_size);
jit->num_params = sig->param_count;
jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
void
mono_debug_serialize_debug_info (MonoCompile *cfg, guint8 **out_buf, guint32 *buf_len)
{
- MiniDebugMethodInfo *info;
MonoDebugMethodJitInfo *jit;
guint32 size, prev_offset, prev_native_offset;
guint8 *buf, *p;
int i;
- info = (MiniDebugMethodInfo *) cfg->debug_info;
- if (!info || !info->jit) {
+ /* Can't use cfg->debug_info as it is freed by close_method () */
+ jit = mono_debug_find_method (cfg->method, mono_domain_get ());
+ if (!jit) {
*buf_len = 0;
return;
}
- jit = info->jit;
size = ((jit->num_params + jit->num_locals + 1) * 10) + (jit->num_line_numbers * 10) + 64;
p = buf = g_malloc (size);
print_var_info (&jit->locals [i], i, "", "Local");
}
}
-}
-
-
-/*
- * Debugger breakpoint interface.
- *
- * This interface is used to insert breakpoints on methods which are not yet JITed.
- * The debugging code keeps a list of all such breakpoints and automatically inserts the
- * breakpoint when the method is JITed.
- */
-
-static GPtrArray *method_breakpoints = NULL;
-
-MonoDebugMethodAddressList *
-mono_debugger_insert_method_breakpoint (MonoMethod *method, guint64 index)
-{
- MiniDebugMethodBreakpointInfo *info;
-
- info = g_new0 (MiniDebugMethodBreakpointInfo, 1);
- info->method = method;
- info->index = index;
-
- info->address_list = mono_debug_lookup_method_addresses (method);
-
- if (!method_breakpoints)
- method_breakpoints = g_ptr_array_new ();
-
- g_ptr_array_add (method_breakpoints, info);
-
- return info->address_list;
-}
-
-int
-mono_debugger_remove_method_breakpoint (guint64 index)
-{
- int i;
-
- if (!method_breakpoints)
- return 0;
-
- for (i = 0; i < method_breakpoints->len; i++) {
- MiniDebugMethodBreakpointInfo *info = g_ptr_array_index (method_breakpoints, i);
-
- if (info->index != index)
- continue;
-
- g_ptr_array_remove (method_breakpoints, info);
- g_free (info->address_list);
- g_free (info);
- return 1;
- }
-
- return 0;
-}
-
-static void
-mono_debugger_check_breakpoints (MonoMethod *method, MonoDebugMethodAddress *debug_info)
-{
- int i;
-
- if (!method_breakpoints)
- return;
-
- if (method->is_inflated)
- method = ((MonoMethodInflated *) method)->declaring;
-
- for (i = 0; i < method_breakpoints->len; i++) {
- MiniDebugMethodBreakpointInfo *info = g_ptr_array_index (method_breakpoints, i);
-
- if (method != info->method)
- continue;
-
- mono_debugger_event (MONO_DEBUGGER_EVENT_JIT_BREAKPOINT,
- (guint64) (gsize) debug_info, info->index);
- }
+ mono_debug_free_method_jit_info (jit);
}
/*
}
void
-mono_debugger_thread_created (gsize tid, MonoJitTlsData *jit_tls)
+mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData *jit_tls)
{
#ifdef MONO_DEBUGGER_SUPPORTED
size_t stsize = 0;
if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
return;
+ mono_debugger_lock ();
+
mono_thread_get_stack_bounds (&staddr, &stsize);
info = g_new0 (MonoDebuggerThreadInfo, 1);
info->tid = tid;
+ info->thread = thread;
info->stack_start = (guint64) (gsize) staddr;
info->signal_stack_start = (guint64) (gsize) jit_tls->signal_stack;
info->stack_size = stsize;
mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_CREATED,
tid, (guint64) (gsize) info);
+
+ mono_debugger_unlock ();
#endif /* MONO_DEBUGGER_SUPPORTED */
}
if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
return;
+ mono_debugger_lock ();
+
for (ptr = &mono_debugger_thread_table; *ptr; ptr = &(*ptr)->next) {
MonoDebuggerThreadInfo *info = *ptr;
g_free (info);
break;
}
+
+ mono_debugger_unlock ();
#endif
}
+
+void
+mono_debugger_extended_notification (MonoDebuggerEvent event, guint64 data, guint64 arg)
+{
+#ifdef MONO_DEBUGGER_SUPPORTED
+ MonoDebuggerThreadInfo **ptr;
+ MonoThread *thread = mono_thread_current ();
+
+ if (!mono_debug_using_mono_debugger ())
+ return;
+
+ mono_debugger_lock ();
+
+ for (ptr = &mono_debugger_thread_table; *ptr; ptr = &(*ptr)->next) {
+ MonoDebuggerThreadInfo *info = *ptr;
+
+ if (info->thread != thread)
+ continue;
+
+ if ((info->extended_notifications & (int) event) == 0)
+ continue;
+
+ mono_debugger_event (event, data, arg);
+ }
+
+ mono_debugger_unlock ();
+#endif
+}
+
+void
+mono_debugger_trampoline_compiled (MonoMethod *method, const guint8 *code)
+{
+ mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_TRAMPOLINE,
+ (guint64) (gsize) method, (guint64) (gsize) code);
+}