*/
MonoThreadUnwindState filter_state;
- /*
- * The callee address of the last mono_runtime_invoke call
- */
- gpointer invoke_addr;
-
gboolean abort_requested;
/*
#define HEADER_LENGTH 11
#define MAJOR_VERSION 2
-#define MINOR_VERSION 40
+#define MINOR_VERSION 42
typedef enum {
CMD_SET_VM = 1,
ERR_NO_INVOCATION = 104,
ERR_ABSENT_INFORMATION = 105,
ERR_NO_SEQ_POINT_AT_IL_OFFSET = 106,
+ ERR_INVOKE_ABORTED = 107,
ERR_LOADER_ERROR = 200, /*XXX extend the protocol to pass this information down the pipe */
} ErrorCode;
/* The single step request instance */
static SingleStepReq *ss_req;
-static gpointer ss_invoke_addr;
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
/* Number of single stepping operations in progress */
static void emit_type_load (gpointer key, gpointer type, gpointer user_data);
-static void start_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
-static void end_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
static void jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result);
static void add_pending_breakpoints (MonoMethod *method, MonoJitInfo *jinfo);
event_requests = g_ptr_array_new ();
mono_mutex_init (&debugger_thread_exited_mutex);
- mono_cond_init (&debugger_thread_exited_cond, NULL);
+ mono_cond_init (&debugger_thread_exited_cond, 0);
mono_profiler_install ((MonoProfiler*)&debugger_profiler, runtime_shutdown);
mono_profiler_set_events (MONO_PROFILE_APPDOMAIN_EVENTS | MONO_PROFILE_THREADS | MONO_PROFILE_ASSEMBLY_EVENTS | MONO_PROFILE_JIT_COMPILATION | MONO_PROFILE_METHOD_EVENTS);
mono_profiler_install_thread (thread_startup, thread_end);
mono_profiler_install_assembly (NULL, assembly_load, assembly_unload, NULL);
mono_profiler_install_jit_end (jit_end);
- mono_profiler_install_method_invoke (start_runtime_invoke, end_runtime_invoke);
mono_native_tls_alloc (&debugger_tls_id, NULL);
/* Needed by the hash_table_new_type () call below */
mono_gc_base_init ();
- thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
- MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls);
+ thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
+ MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
- tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
- MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread);
+ tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread table");
+ MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread table");
- tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
- MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj);
+ tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread object table");
+ MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread object table");
pending_assembly_loads = g_ptr_array_new ();
domains = g_hash_table_new (mono_aligned_addr_hash, NULL);
{
objrefs = g_hash_table_new_full (NULL, NULL, NULL, free_objref);
obj_to_objref = g_hash_table_new (NULL, NULL);
- suspended_objs = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
- MONO_GC_REGISTER_ROOT_FIXED (suspended_objs);
+ suspended_objs = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
+ MONO_GC_REGISTER_ROOT_FIXED (suspended_objs, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
}
static void
suspend_init (void)
{
mono_mutex_init (&suspend_mutex);
- mono_cond_init (&suspend_cond, NULL);
+ mono_cond_init (&suspend_cond, 0);
MONO_SEM_INIT (&suspend_sem, 0);
}
g_assert (!tls);
// FIXME: Free this somewhere
tls = g_new0 (DebuggerTlsData, 1);
- MONO_GC_REGISTER_ROOT_SINGLE (tls->thread);
+ MONO_GC_REGISTER_ROOT_SINGLE (tls->thread, MONO_ROOT_SOURCE_DEBUGGER, "debugger thread reference");
tls->thread = thread;
mono_native_tls_set_value (debugger_tls_id, tls);
clear_types_for_assembly (assembly);
}
-static void
-start_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
-#if defined(HOST_WIN32) && !defined(__GNUC__)
- gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
- gpointer stackptr = __builtin_frame_address (1);
-#endif
- MonoInternalThread *thread = mono_thread_internal_current ();
- DebuggerTlsData *tls;
-
- mono_loader_lock ();
-
- tls = mono_g_hash_table_lookup (thread_to_tls, thread);
- /* Could be the debugger thread with assembly/type load hooks */
- if (tls)
- tls->invoke_addr = stackptr;
-
- mono_loader_unlock ();
-}
-
-static void
-end_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
- int i;
-#if defined(HOST_WIN32) && !defined(__GNUC__)
- gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
- gpointer stackptr = __builtin_frame_address (1);
-#endif
-
- if (!embedding || ss_req == NULL || stackptr != ss_invoke_addr || ss_req->thread != mono_thread_internal_current ())
- return;
-
- /*
- * We need to stop single stepping when exiting a runtime invoke, since if it is
- * a step out, it may return to native code, and thus never end.
- */
- mono_loader_lock ();
- ss_invoke_addr = NULL;
-
- for (i = 0; i < event_requests->len; ++i) {
- EventRequest *req = g_ptr_array_index (event_requests, i);
-
- if (req->event_kind == EVENT_KIND_STEP) {
- ss_destroy (req->info);
- g_ptr_array_remove_index_fast (event_requests, i);
- g_free (req);
- break;
- }
- }
- mono_loader_unlock ();
-}
-
static void
send_type_load (MonoClass *klass)
{
if (!found) {
MonoMethod *declaring = NULL;
+ jmethod = jinfo_get_method (ji);
if (jmethod->is_inflated)
declaring = mono_method_get_declaring_generic_method (jmethod);
- jmethod = jinfo_get_method (ji);
mono_domain_lock (domain);
seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, jmethod);
if (!seq_points && declaring)
mono_loader_unlock ();
process_event (EVENT_KIND_USER_BREAK, NULL, 0, &ctx, events, suspend_policy);
- } else {
+ } else if (debug_options.native_debugger_break) {
G_BREAKPOINT ();
}
}
if (val == 1)
mono_arch_start_single_stepping ();
-
- if (ss_req != NULL && ss_invoke_addr == NULL) {
- DebuggerTlsData *tls;
-
- mono_loader_lock ();
-
- tls = mono_g_hash_table_lookup (thread_to_tls, ss_req->thread);
- ss_invoke_addr = tls->invoke_addr;
-
- mono_loader_unlock ();
- }
#else
g_assert_not_reached ();
#endif
if (val == 0)
mono_arch_stop_single_stepping ();
- if (ss_req != NULL)
- ss_invoke_addr = NULL;
#else
g_assert_not_reached ();
#endif
err = do_invoke_method (tls, &buf, invoke, p, &p);
}
+ if (tls->abort_requested) {
+ if (CHECK_PROTOCOL_VERSION (2, 42))
+ err = ERR_INVOKE_ABORTED;
+ }
+
/* Start suspending before sending the reply */
if (mindex == invoke->nmethods - 1) {
if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED)) {
g_assert (tls);
if (tls->abort_requested) {
+ DEBUG_PRINTF (1, "Abort already requested.\n");
mono_loader_unlock ();
break;
}
break;
}
case CMD_METHOD_GET_LOCALS_INFO: {
- int i, j, num_locals;
+ int i, num_locals;
MonoDebugLocalsInfo *locals;
int *locals_map = NULL;
buffer_add_int (buf, header->code_size);
}
} else {
- /* Maps between the IL locals index and the index in locals->locals */
- locals_map = g_new0 (int, header->num_locals);
- for (i = 0; i < header->num_locals; ++i)
- locals_map [i] = -1;
num_locals = locals->num_locals;
- for (i = 0; i < num_locals; ++i) {
- g_assert (locals->locals [i].index < header->num_locals);
- locals_map [locals->locals [i].index] = i;
- }
buffer_add_int (buf, num_locals);
/* Types */
- for (i = 0; i < header->num_locals; ++i) {
- if (locals_map [i] != -1)
- buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
+ for (i = 0; i < num_locals; ++i) {
+ g_assert (locals->locals [i].index < header->num_locals);
+ buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [locals->locals [i].index]));
}
-
/* Names */
- for (i = 0; i < header->num_locals; ++i) {
- if (locals_map [i] != -1)
- buffer_add_string (buf, locals->locals [locals_map [i]].name);
- }
-
+ for (i = 0; i < num_locals; ++i)
+ buffer_add_string (buf, locals->locals [i].name);
/* Scopes */
- for (i = 0; i < header->num_locals; ++i) {
- if (locals_map [i] != -1) {
- j = locals_map [i];
- if (locals->locals [j].block) {
- buffer_add_int (buf, locals->locals [j].block->start_offset);
- buffer_add_int (buf, locals->locals [j].block->end_offset);
- } else {
- buffer_add_int (buf, 0);
- buffer_add_int (buf, header->code_size);
- }
+ for (i = 0; i < num_locals; ++i) {
+ if (locals->locals [i].block) {
+ buffer_add_int (buf, locals->locals [i].block->start_offset);
+ buffer_add_int (buf, locals->locals [i].block->end_offset);
+ } else {
+ buffer_add_int (buf, 0);
+ buffer_add_int (buf, header->code_size);
}
}
}
char *s;
int i, index, length;
gunichar2 *c;
+ gboolean use_utf16 = FALSE;
objid = decode_objid (p, &p, end);
err = get_object (objid, (MonoObject**)&str);
switch (command) {
case CMD_STRING_REF_GET_VALUE:
- s = mono_string_to_utf8 (str);
- buffer_add_string (buf, s);
- g_free (s);
+ if (CHECK_PROTOCOL_VERSION (2, 41)) {
+ for (i = 0; i < mono_string_length (str); ++i)
+ if (mono_string_chars (str)[i] == 0)
+ use_utf16 = TRUE;
+ buffer_add_byte (buf, use_utf16 ? 1 : 0);
+ }
+ if (use_utf16) {
+ buffer_add_int (buf, mono_string_length (str) * 2);
+ buffer_add_data (buf, (guint8*)mono_string_chars (str), mono_string_length (str) * 2);
+ } else {
+ s = mono_string_to_utf8 (str);
+ buffer_add_string (buf, s);
+ g_free (s);
+ }
break;
case CMD_STRING_REF_GET_LENGTH:
buffer_add_long (buf, mono_string_length (str));