X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmini%2Fdebugger-agent.c;h=990ee09e107f394773e825d8f1711094b5a871f3;hb=a4ac636499cf00012912daeeb9218bda305068c0;hp=f0891b45658f21e4acc2fb55cb673c0634c07936;hpb=fc420daefb85899617c3946a3919618eef13df29;p=mono.git diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index f0891b45658..990ee09e107 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -268,7 +268,7 @@ typedef struct { #define HEADER_LENGTH 11 #define MAJOR_VERSION 2 -#define MINOR_VERSION 41 +#define MINOR_VERSION 42 typedef enum { CMD_SET_VM = 1, @@ -325,6 +325,7 @@ typedef enum { 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; @@ -661,7 +662,7 @@ static MonoGHashTable *tid_to_thread; /* Protected by the loader lock */ static MonoGHashTable *tid_to_thread_obj; -static gsize debugger_thread_id; +static MonoNativeThreadId debugger_thread_id; static HANDLE debugger_thread_handle; @@ -810,7 +811,7 @@ register_socket_transport (void); static inline gboolean is_debugger_thread (void) { - return GetCurrentThreadId () == debugger_thread_id; + return mono_native_thread_id_equals (mono_native_thread_id_get (), debugger_thread_id); } static int @@ -973,7 +974,7 @@ mono_debugger_agent_init (void) 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); @@ -1601,7 +1602,7 @@ stop_debugger_thread (void) * If we continue with the shutdown without waiting for it, then the client might * not receive an answer to its last command like a resume. */ - if (GetCurrentThreadId () != debugger_thread_id) { + if (!is_debugger_thread ()) { do { MONO_TRY_BLOCKING; mono_mutex_lock (&debugger_thread_exited_mutex); @@ -2391,10 +2392,10 @@ buffer_add_typeid (Buffer *buf, MonoDomain *domain, MonoClass *klass) char *s; s = mono_type_full_name (&klass->byval_arg); - if (GetCurrentThreadId () == debugger_thread_id) + if (is_debugger_thread ()) DEBUG_PRINTF (2, "[dbg] send class [%s]\n", s); else - DEBUG_PRINTF (2, "[%p] send class [%s]\n", (gpointer)GetCurrentThreadId (), s); + DEBUG_PRINTF (2, "[%p] send class [%s]\n", (gpointer)mono_native_thread_id_get (), s); g_free (s); } } @@ -2491,7 +2492,7 @@ 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); } @@ -2501,6 +2502,7 @@ typedef struct gboolean last_frame_set; MonoContext ctx; gpointer lmf; + MonoDomain *domain; } GetLastFrameUserData; static gboolean @@ -2520,19 +2522,32 @@ get_last_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data) /* Store the context/lmf for the frame above the last frame */ memcpy (&data->ctx, ctx, sizeof (MonoContext)); data->lmf = info->lmf; + data->domain = info->domain; return TRUE; } } +static void +copy_unwind_state_from_frame_data (MonoThreadUnwindState *to, GetLastFrameUserData *data, gpointer jit_tls) +{ + memcpy (&to->ctx, &data->ctx, sizeof (MonoContext)); + + to->unwind_data [MONO_UNWIND_DATA_DOMAIN] = data->domain; + to->unwind_data [MONO_UNWIND_DATA_LMF] = data->lmf; + to->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls; + to->valid = TRUE; +} + /* * thread_interrupt: * * Process interruption of a thread. This should be signal safe. + * + * This always runs in the debugger thread. */ static void thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) { - gboolean res; gpointer ip; MonoNativeThreadId tid; @@ -2555,7 +2570,6 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) * tls->suspending flag to avoid races when that happens. */ if (!tls->suspended && !tls->suspending) { - MonoContext ctx; GetLastFrameUserData data; // FIXME: printf is not signal safe, but this is only used during @@ -2581,15 +2595,12 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) data.last_frame_set = FALSE; mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &data); if (data.last_frame_set) { + gpointer jit_tls = ((MonoThreadInfo*)tls->thread->thread_info)->jit_data; + memcpy (&tls->async_last_frame, &data.last_frame, sizeof (StackFrameInfo)); - res = mono_thread_state_init_from_monoctx (&tls->async_state, &ctx); - g_assert (res); - mono_thread_state_init_from_monoctx (&tls->context, &ctx); - g_assert (res); - memcpy (&tls->async_state.ctx, &data.ctx, sizeof (MonoContext)); - tls->async_state.unwind_data [MONO_UNWIND_DATA_LMF] = data.lmf; - tls->async_state.unwind_data [MONO_UNWIND_DATA_JIT_TLS] = ((MonoThreadInfo*)tls->thread->thread_info)->jit_data; + copy_unwind_state_from_frame_data (&tls->async_state, &data, jit_tls); + copy_unwind_state_from_frame_data (&tls->context, &data, jit_tls); } else { tls->async_state.valid = FALSE; } @@ -2657,12 +2668,12 @@ notify_thread (gpointer key, gpointer value, gpointer user_data) { MonoInternalThread *thread = key; DebuggerTlsData *tls = value; - gsize tid = thread->tid; + MonoNativeThreadId tid = MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid); - if (GetCurrentThreadId () == tid || tls->terminated) + if (mono_native_thread_id_equals (mono_native_thread_id_get (), tid) || tls->terminated) return; - DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid); + DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer)mono_native_thread_id_get (), (gpointer)tid); /* This is _not_ equivalent to ves_icall_System_Threading_Thread_Abort () */ InterruptData interrupt_data = { 0 }; @@ -2670,7 +2681,7 @@ notify_thread (gpointer key, gpointer value, gpointer user_data) mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gpointer)(gsize)thread->tid, FALSE, debugger_interrupt_critical, &interrupt_data); if (!interrupt_data.valid_info) { - DEBUG_PRINTF (1, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid); + DEBUG_PRINTF (1, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer)mono_native_thread_id_get (), (gpointer)tid); /* * Attached thread which died without detaching. */ @@ -2694,14 +2705,14 @@ process_suspend (DebuggerTlsData *tls, MonoContext *ctx) return; } - if (debugger_thread_id == GetCurrentThreadId ()) + if (is_debugger_thread ()) return; /* Prevent races with mono_debugger_agent_thread_interrupt () */ if (suspend_count - tls->resume_count > 0) tls->suspending = TRUE; - DEBUG_PRINTF (1, "[%p] Received single step event for suspending.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Received single step event for suspending.\n", (gpointer)mono_native_thread_id_get ()); if (suspend_count - tls->resume_count == 0) { /* @@ -2709,7 +2720,7 @@ process_suspend (DebuggerTlsData *tls, MonoContext *ctx) * suspending is still active. * FIXME: This slows down single threaded invokes. */ - DEBUG_PRINTF (1, "[%p] Ignored during single threaded invoke.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Ignored during single threaded invoke.\n", (gpointer)mono_native_thread_id_get ()); return; } @@ -2742,7 +2753,7 @@ suspend_vm (void) suspend_count ++; - DEBUG_PRINTF (1, "[%p] Suspending vm...\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Suspending vm...\n", (gpointer)mono_native_thread_id_get ()); if (suspend_count == 1) { // FIXME: Is it safe to call this inside the lock ? @@ -2772,7 +2783,7 @@ resume_vm (void) { int err; - g_assert (debugger_thread_id == GetCurrentThreadId ()); + g_assert (is_debugger_thread ()); mono_loader_lock (); @@ -2783,7 +2794,7 @@ resume_vm (void) g_assert (suspend_count > 0); suspend_count --; - DEBUG_PRINTF (1, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)GetCurrentThreadId (), suspend_count); + DEBUG_PRINTF (1, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)mono_native_thread_id_get (), suspend_count); if (suspend_count == 0) { // FIXME: Is it safe to call this inside the lock ? @@ -2815,7 +2826,7 @@ resume_thread (MonoInternalThread *thread) int err; DebuggerTlsData *tls; - g_assert (debugger_thread_id == GetCurrentThreadId ()); + g_assert (is_debugger_thread ()); mono_loader_lock (); @@ -2886,7 +2897,7 @@ suspend_current (void) DebuggerTlsData *tls; int err; - g_assert (debugger_thread_id != GetCurrentThreadId ()); + g_assert (!is_debugger_thread ()); if (mono_loader_lock_is_owned_by_self ()) { /* @@ -2911,7 +2922,7 @@ suspend_current (void) MONO_SEM_POST (&suspend_sem); } - DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)mono_native_thread_id_get ()); MONO_TRY_BLOCKING; while (suspend_count - tls->resume_count > 0) { @@ -2927,7 +2938,7 @@ suspend_current (void) mono_mutex_unlock (&suspend_mutex); - DEBUG_PRINTF (1, "[%p] Resumed.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Resumed.\n", (gpointer)mono_native_thread_id_get ()); if (tls->pending_invoke) { /* Save the original context */ @@ -3008,12 +3019,12 @@ is_suspended (void) } static void -no_seq_points_found (MonoMethod *method) +no_seq_points_found (MonoMethod *method, int offset) { /* * This can happen in full-aot mode with assemblies AOTed without the 'soft-debug' option to save space. */ - printf ("Unable to find seq points for method '%s'.\n", mono_method_full_name (method, TRUE)); + printf ("Unable to find seq points for method '%s', offset 0x%x.\n", mono_method_full_name (method, TRUE), offset); } typedef struct { @@ -3242,7 +3253,7 @@ emit_appdomain_load (gpointer key, gpointer value, gpointer user_data) static void emit_thread_start (gpointer key, gpointer value, gpointer user_data) { - if (GPOINTER_TO_INT (key) != debugger_thread_id) + if (!mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (GPOINTER_TO_UINT (key)), debugger_thread_id)) process_profiler_event (EVENT_KIND_THREAD_START, value); } @@ -3599,14 +3610,14 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx if (agent_config.defer) { /* Make sure the thread id is always set when doing deferred debugging */ - if (debugger_thread_id == GetCurrentThreadId ()) { + if (is_debugger_thread ()) { /* Don't suspend on events from the debugger thread */ suspend_policy = SUSPEND_POLICY_NONE; thread = mono_thread_get_main (); } else thread = mono_thread_current (); } else { - if (debugger_thread_id == GetCurrentThreadId () && event != EVENT_KIND_VM_DEATH) + if (is_debugger_thread () && event != EVENT_KIND_VM_DEATH) // FIXME: Send these with a NULL thread, don't suspend the current thread return; } @@ -3743,7 +3754,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx vm_start_event_sent = TRUE; } - DEBUG_PRINTF (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer)GetCurrentThreadId (), nevents, event_to_string (event), ecount, suspend_policy); + DEBUG_PRINTF (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer)mono_native_thread_id_get (), nevents, event_to_string (event), ecount, suspend_policy); switch (suspend_policy) { case SUSPEND_POLICY_NONE: @@ -3801,13 +3812,13 @@ thread_startup (MonoProfiler *prof, uintptr_t tid) MonoInternalThread *old_thread; DebuggerTlsData *tls; - if (tid == debugger_thread_id) + if (mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (tid), debugger_thread_id)) return; - g_assert (thread->tid == tid); + g_assert (mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (tid), MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid))); mono_loader_lock (); - old_thread = mono_g_hash_table_lookup (tid_to_thread, (gpointer)tid); + old_thread = mono_g_hash_table_lookup (tid_to_thread, GUINT_TO_POINTER (tid)); mono_loader_unlock (); if (old_thread) { if (thread == old_thread) { @@ -3815,18 +3826,18 @@ thread_startup (MonoProfiler *prof, uintptr_t tid) * For some reason, thread_startup () might be called for the same thread * multiple times (attach ?). */ - DEBUG_PRINTF (1, "[%p] thread_start () called multiple times for %p, ignored.\n", (gpointer)tid, (gpointer)tid); + DEBUG_PRINTF (1, "[%p] thread_start () called multiple times for %p, ignored.\n", GUINT_TO_POINTER (tid), GUINT_TO_POINTER (tid)); return; } else { /* * thread_end () might not be called for some threads, and the tid could * get reused. */ - DEBUG_PRINTF (1, "[%p] Removing stale data for tid %p.\n", (gpointer)tid, (gpointer)tid); + DEBUG_PRINTF (1, "[%p] Removing stale data for tid %p.\n", GUINT_TO_POINTER (tid), GUINT_TO_POINTER (tid)); mono_loader_lock (); mono_g_hash_table_remove (thread_to_tls, old_thread); - mono_g_hash_table_remove (tid_to_thread, (gpointer)tid); - mono_g_hash_table_remove (tid_to_thread_obj, (gpointer)tid); + mono_g_hash_table_remove (tid_to_thread, GUINT_TO_POINTER (tid)); + mono_g_hash_table_remove (tid_to_thread_obj, GUINT_TO_POINTER (tid)); mono_loader_unlock (); } } @@ -3844,7 +3855,7 @@ thread_startup (MonoProfiler *prof, uintptr_t tid) mono_loader_lock (); mono_g_hash_table_insert (thread_to_tls, thread, tls); mono_g_hash_table_insert (tid_to_thread, (gpointer)tid, thread); - mono_g_hash_table_insert (tid_to_thread_obj, (gpointer)tid, mono_thread_current ()); + mono_g_hash_table_insert (tid_to_thread_obj, GUINT_TO_POINTER (tid), mono_thread_current ()); mono_loader_unlock (); process_profiler_event (EVENT_KIND_THREAD_START, thread); @@ -3862,9 +3873,9 @@ thread_end (MonoProfiler *prof, uintptr_t tid) DebuggerTlsData *tls = NULL; mono_loader_lock (); - thread = mono_g_hash_table_lookup (tid_to_thread, (gpointer)tid); + thread = mono_g_hash_table_lookup (tid_to_thread, GUINT_TO_POINTER (tid)); if (thread) { - mono_g_hash_table_remove (tid_to_thread_obj, (gpointer)tid); + mono_g_hash_table_remove (tid_to_thread_obj, GUINT_TO_POINTER (tid)); tls = mono_g_hash_table_lookup (thread_to_tls, thread); if (tls) { /* FIXME: Maybe we need to free this instead, but some code can't handle that */ @@ -3880,7 +3891,9 @@ thread_end (MonoProfiler *prof, uintptr_t tid) if (thread) { DEBUG_PRINTF (1, "[%p] Thread terminated, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls); - if (GetCurrentThreadId () == tid && !mono_native_tls_get_value (debugger_tls_id)) { + if (mono_native_thread_id_equals (mono_native_thread_id_get (), MONO_UINT_TO_NATIVE_THREAD_ID (tid)) + && !mono_native_tls_get_value (debugger_tls_id) + ) { /* * This can happen on darwin since we deregister threads using pthread dtors. * process_profiler_event () and the code it calls cannot handle a null TLS value. @@ -4517,7 +4530,7 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t /* * These seq points are inserted by the JIT after calls, step over needs to skip them. */ - DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset); + DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping over, continuing single stepping.\n", (gpointer)mono_native_thread_id_get (), sp->il_offset); return FALSE; } @@ -4527,7 +4540,7 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t compute_frame_info (tls->thread, tls); if (req->nframes && tls->frame_count && tls->frame_count > req->nframes) { /* Hit the breakpoint in a recursive call */ - DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer)mono_native_thread_id_get ()); return FALSE; } } @@ -4538,7 +4551,7 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t mono_thread_state_init_from_monoctx (&tls->context, ctx); compute_frame_info (tls->thread, tls); if (ss_req->start_method == method && req->nframes && tls->frame_count == req->nframes) {//Check also frame count(could be recursion) - DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset); + DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer)mono_native_thread_id_get (), sp->il_offset); return FALSE; } } @@ -4554,11 +4567,11 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t loc = mono_debug_symfile_lookup_location (minfo, sp->il_offset); if (!loc) { - DEBUG_PRINTF (1, "[%p] No line number info for il offset %x, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset); + DEBUG_PRINTF (1, "[%p] No line number info for il offset %x, continuing single stepping.\n", (gpointer)mono_native_thread_id_get (), sp->il_offset); ss_req->last_method = method; hit = FALSE; } else if (loc && method == ss_req->last_method && loc->row == ss_req->last_line) { - DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer)GetCurrentThreadId (), loc->row); + DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer)mono_native_thread_id_get (), loc->row); hit = FALSE; } @@ -4627,11 +4640,11 @@ process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal) found_sp = mono_find_prev_seq_point_for_native_offset (mono_domain_get (), method, native_offset, &info, &sp); if (!found_sp) - no_seq_points_found (method); + no_seq_points_found (method, native_offset); g_assert (found_sp); - DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, [il=0x%x,native=0x%x].\n", (gpointer)GetCurrentThreadId (), method->name, ip, sp.il_offset, native_offset); + DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, [il=0x%x,native=0x%x].\n", (gpointer)mono_native_thread_id_get (), method->name, ip, sp.il_offset, native_offset); bp = NULL; for (i = 0; i < breakpoints->len; ++i) { @@ -4738,7 +4751,7 @@ resume_from_signal_handler (void *sigctx, void *func) // FIXME: This might not work on an altstack ? tls = mono_native_tls_get_value (debugger_tls_id); if (!tls) - fprintf (stderr, "Thread %p is not attached to the JIT.\n", (gpointer)GetCurrentThreadId ()); + fprintf (stderr, "Thread %p is not attached to the JIT.\n", (gpointer)mono_native_thread_id_get ()); g_assert (tls); // FIXME: MonoContext usually doesn't include the fp registers, so these are @@ -4803,7 +4816,7 @@ mono_debugger_agent_user_break (void) 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 (); } } @@ -4859,7 +4872,7 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal) if (log_level > 0) { ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain); - DEBUG_PRINTF (1, "[%p] Single step event (depth=%s) at %s (%p)[0x%x], sp %p, last sp %p\n", (gpointer)GetCurrentThreadId (), ss_depth_to_string (ss_req->depth), mono_method_full_name (jinfo_get_method (ji), TRUE), MONO_CONTEXT_GET_IP (ctx), (int)((guint8*)MONO_CONTEXT_GET_IP (ctx) - (guint8*)ji->code_start), MONO_CONTEXT_GET_SP (ctx), ss_req->last_sp); + DEBUG_PRINTF (1, "[%p] Single step event (depth=%s) at %s (%p)[0x%x], sp %p, last sp %p\n", (gpointer)mono_native_thread_id_get (), ss_depth_to_string (ss_req->depth), mono_method_full_name (jinfo_get_method (ji), TRUE), MONO_CONTEXT_GET_IP (ctx), (int)((guint8*)MONO_CONTEXT_GET_IP (ctx) - (guint8*)ji->code_start), MONO_CONTEXT_GET_SP (ctx), ss_req->last_sp); } ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain); @@ -4935,7 +4948,7 @@ mono_debugger_agent_single_step_event (void *sigctx) // be as fast as possible. Move the relevant code from process_single_step_inner () // here - if (GetCurrentThreadId () == debugger_thread_id) { + if (is_debugger_thread ()) { /* * This could happen despite our best effors when the runtime calls * assembly/type resolve hooks. @@ -4958,7 +4971,7 @@ debugger_agent_single_step_from_context (MonoContext *ctx) DebuggerTlsData *tls; MonoThreadUnwindState orig_restore_state; - if (GetCurrentThreadId () == debugger_thread_id) + if (is_debugger_thread ()) return; tls = mono_native_tls_get_value (debugger_tls_id); @@ -4982,7 +4995,7 @@ debugger_agent_breakpoint_from_context (MonoContext *ctx) MonoThreadUnwindState orig_restore_state; guint8 *orig_ip; - if (GetCurrentThreadId () == debugger_thread_id) + if (is_debugger_thread ()) return; orig_ip = MONO_CONTEXT_GET_IP (ctx); @@ -5312,7 +5325,7 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte found_sp = mono_find_next_seq_point_for_native_offset (frame.domain, frame.method, frame.native_offset, &info, &local_sp); sp = (found_sp)? &local_sp : NULL; if (!sp) - no_seq_points_found (frame.method); + no_seq_points_found (frame.method, frame.native_offset); g_assert (sp); method = frame.method; @@ -5358,7 +5371,7 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte found_sp = mono_find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp); sp = (found_sp)? &local_sp : NULL; if (!sp) - no_seq_points_found (frame->method); + no_seq_points_found (frame->method, frame->native_offset); g_assert (sp); method = frame->method; } @@ -5872,7 +5885,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 if (t && klass != mono_class_from_mono_type (t)) { char *name = mono_type_full_name (t); char *name2 = mono_type_full_name (&klass->byval_arg); - DEBUG_PRINTF (1, "[%p] Expected value of type %s, got %s.\n", (gpointer)GetCurrentThreadId (), name, name2); + DEBUG_PRINTF (1, "[%p] Expected value of type %s, got %s.\n", (gpointer)mono_native_thread_id_get (), name, name2); g_free (name); g_free (name2); return ERR_INVALID_ARGUMENT; @@ -5908,7 +5921,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, !(t->type == MONO_TYPE_GENERICINST && type == MONO_TYPE_VALUETYPE) && !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_OBJECT)) { char *name = mono_type_full_name (t); - DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type); + DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)mono_native_thread_id_get (), name, type); g_free (name); return ERR_INVALID_ARGUMENT; } @@ -6052,7 +6065,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, g_free (vtype_buf); } else { char *name = mono_type_full_name (t); - DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type); + DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)mono_native_thread_id_get (), name, type); g_free (name); return ERR_INVALID_ARGUMENT; } @@ -6465,7 +6478,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 * Invoke this method directly, currently only Environment.Exit () is supported. */ this_arg = NULL; - DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (invoke->method, TRUE), this_arg ? this_arg->vtable->klass->name : ""); + DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)mono_native_thread_id_get (), mono_method_full_name (invoke->method, TRUE), this_arg ? this_arg->vtable->klass->name : ""); mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc); g_assert_not_reached (); } @@ -6483,7 +6496,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 /* Should be null */ int type = decode_byte (p, &p, end); if (type != VALUE_TYPE_ID_NULL) { - DEBUG_PRINTF (1, "[%p] Error: Static vtype method invoked with this argument.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Error: Static vtype method invoked with this argument.\n", (gpointer)mono_native_thread_id_get ()); return ERR_INVALID_ARGUMENT; } memset (this_buf, 0, mono_class_instance_size (m->klass)); @@ -6513,7 +6526,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 if (MONO_CLASS_IS_INTERFACE (m->klass)) { if (!this_arg) { - DEBUG_PRINTF (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer)mono_native_thread_id_get ()); return ERR_INVALID_ARGUMENT; } m = mono_object_get_virtual_method (this_arg, m); @@ -6524,7 +6537,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 } } else if ((m->flags & METHOD_ATTRIBUTE_VIRTUAL) && !m->klass->valuetype && invoke->flags & INVOKE_FLAG_VIRTUAL) { if (!this_arg) { - DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)mono_native_thread_id_get ()); return ERR_INVALID_ARGUMENT; } m = mono_object_get_virtual_method (this_arg, m); @@ -6534,7 +6547,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 } } - DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this_arg ? this_arg->vtable->klass->name : ""); + DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)mono_native_thread_id_get (), mono_method_full_name (m, TRUE), this_arg ? this_arg->vtable->klass->name : ""); if (this_arg && this_arg->vtable->domain != domain) NOT_IMPLEMENTED; @@ -6616,7 +6629,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 else res = mono_runtime_invoke (m, this_arg, args, &exc); mono_stopwatch_stop (&watch); - DEBUG_PRINTF (1, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer)GetCurrentThreadId (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch)); + DEBUG_PRINTF (1, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer)mono_native_thread_id_get (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch)); if (exc) { buffer_add_byte (buf, 0); buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &exc, domain); @@ -6735,6 +6748,11 @@ invoke_method (void) 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)) { @@ -6758,7 +6776,7 @@ invoke_method (void) tls->resume_count -= invoke->suspend_count; } - DEBUG_PRINTF (1, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer)GetCurrentThreadId (), err, tls->resume_count); + DEBUG_PRINTF (1, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer)mono_native_thread_id_get (), err, tls->resume_count); /* * Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE: @@ -7051,6 +7069,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) g_assert (tls); if (tls->abort_requested) { + DEBUG_PRINTF (1, "Abort already requested.\n"); mono_loader_unlock (); break; } @@ -8404,7 +8423,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g break; } case CMD_METHOD_GET_LOCALS_INFO: { - int i, j, num_locals; + int i, num_locals; MonoDebugLocalsInfo *locals; int *locals_map = NULL; @@ -8431,40 +8450,25 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g 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); } } } @@ -9581,9 +9585,9 @@ debugger_thread (void *arg) gboolean no_reply; gboolean attach_failed = FALSE; - DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer)GetCurrentThreadId ()); + DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer)mono_native_thread_id_get ()); - debugger_thread_id = GetCurrentThreadId (); + debugger_thread_id = mono_native_thread_id_get (); mono_jit_thread_attach (mono_get_root_domain ());