Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mono / mini / debugger-agent.c
index 777d1ed73d3c4f0fce8f32d3c5a7bbda2da90cc0..dcecc4dfb05f191a8cd5d187d3d271ff44410c8f 100644 (file)
@@ -1607,25 +1607,13 @@ 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.
-        * The WaitForSingleObject infrastructure doesn't seem to work during shutdown, so
-        * use pthreads.
         */
-       //WaitForSingleObject (debugger_thread_handle, INFINITE);
        if (GetCurrentThreadId () != debugger_thread_id) {
                do {
                        MONO_TRY_BLOCKING
                        mono_mutex_lock (&debugger_thread_exited_mutex);
-                       if (!debugger_thread_exited) {
-#ifdef HOST_WIN32
-                               if (WAIT_TIMEOUT == WaitForSingleObject(debugger_thread_exited_cond, 0)) {
-                                       mono_mutex_unlock (&debugger_thread_exited_mutex);
-                                       Sleep(1);
-                                       mono_mutex_lock (&debugger_thread_exited_mutex);
-                               }
-#else
+                       if (!debugger_thread_exited)
                                mono_cond_wait (&debugger_thread_exited_cond, &debugger_thread_exited_mutex);
-#endif
-                       }
                        mono_mutex_unlock (&debugger_thread_exited_mutex);
                        MONO_FINISH_TRY_BLOCKING
                } while (!debugger_thread_exited);
@@ -2903,10 +2891,8 @@ invalidate_frames (DebuggerTlsData *tls)
 static void
 suspend_current (void)
 {
-#ifndef HOST_WIN32
-       int err;
-#endif
        DebuggerTlsData *tls;
+       int err;
 
        g_assert (debugger_thread_id != GetCurrentThreadId ());
 
@@ -2937,20 +2923,8 @@ suspend_current (void)
 
        MONO_TRY_BLOCKING
        while (suspend_count - tls->resume_count > 0) {
-#ifdef HOST_WIN32
-               if (WAIT_TIMEOUT == WaitForSingleObject(suspend_cond, 0))
-               {
-                       mono_mutex_unlock (&suspend_mutex);
-                       Sleep(1);
-                       mono_mutex_lock (&suspend_mutex);
-               }
-               else
-               {
-               }
-#else
                err = mono_cond_wait (&suspend_cond, &suspend_mutex);
                g_assert (err == 0);
-#endif
        }
        MONO_FINISH_TRY_BLOCKING
 
@@ -3089,7 +3063,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
        if (info->il_offset == -1) {
                /* mono_debug_il_offset_from_address () doesn't seem to be precise enough (#2092) */
                if (ud->frames == NULL) {
-                       if (find_prev_seq_point_for_native_offset (info->domain, method, info->native_offset, NULL, &sp))
+                       if (mono_find_prev_seq_point_for_native_offset (info->domain, method, info->native_offset, NULL, &sp))
                                info->il_offset = sp.il_offset;
                }
                if (info->il_offset == -1)
@@ -3479,7 +3453,7 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo
                                                MonoDebugMethodInfo *minfo = mono_debug_lookup_method (method);
 
                                                if (minfo) {
-                                                       mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                                                       mono_debug_get_seq_points (minfo, &source_file, &source_file_list, NULL, NULL, NULL);
                                                        for (i = 0; i < source_file_list->len; ++i) {
                                                                sinfo = g_ptr_array_index (source_file_list, i);
                                                                /*
@@ -4202,8 +4176,8 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
        if (error)
                mono_error_init (error);
 
-       seq_point_iterator_init (&it, seq_points);
-       while (seq_point_iterator_next (&it)) {
+       mono_seq_point_iterator_init (&it, seq_points);
+       while (mono_seq_point_iterator_next (&it)) {
                if (it.seq_point.il_offset == bp->il_offset) {
                        it_has_sp = TRUE;
                        break;
@@ -4215,8 +4189,8 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
                 * The set of IL offsets with seq points doesn't completely match the
                 * info returned by CMD_METHOD_GET_DEBUG_INFO (#407).
                 */
-               seq_point_iterator_init (&it, seq_points);
-               while (seq_point_iterator_next (&it)) {
+               mono_seq_point_iterator_init (&it, seq_points);
+               while (mono_seq_point_iterator_next (&it)) {
                        if (it.seq_point.il_offset != METHOD_ENTRY_IL_OFFSET &&
                                it.seq_point.il_offset != METHOD_EXIT_IL_OFFSET &&
                                it.seq_point.il_offset + 1 == bp->il_offset) {
@@ -4229,8 +4203,8 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
        if (!it_has_sp) {
                char *s = g_strdup_printf ("Unable to insert breakpoint at %s:%d", mono_method_full_name (jinfo_get_method (ji), TRUE), bp->il_offset);
 
-               seq_point_iterator_init (&it, seq_points);
-               while (seq_point_iterator_next (&it))
+               mono_seq_point_iterator_init (&it, seq_points);
+               while (mono_seq_point_iterator_next (&it))
                        DEBUG_PRINTF (1, "%d\n", it.seq_point.il_offset);
 
                if (error) {
@@ -4688,7 +4662,7 @@ process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal)
         * The ip points to the instruction causing the breakpoint event, which is after
         * the offset recorded in the seq point map, so find the prev seq point before ip.
         */
-       found_sp = find_prev_seq_point_for_native_offset (mono_domain_get (), method, native_offset, &info, &sp);
+       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);
@@ -4946,7 +4920,7 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
         * The ip points to the instruction causing the single step event, which is before
         * the offset recorded in the seq point map, so find the next seq point after ip.
         */
-       if (!find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info, &sp))
+       if (!mono_find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info, &sp))
                return;
 
        il_offset = sp.il_offset;
@@ -5187,7 +5161,7 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                                StackFrame *frame = frames [frame_index];
 
                                method = frame->method;
-                               found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
+                               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;
                                frame_index ++;
                                if (sp && sp->next_len != 0)
@@ -5202,7 +5176,7 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                                        StackFrame *frame = frames [frame_index];
 
                                        method = frame->method;
-                                       found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
+                                       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 && sp->next_len != 0)
                                                break;
@@ -5215,7 +5189,7 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                                        StackFrame *frame = frames [frame_index];
 
                                        parent_sp_method = frame->method;
-                                       found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &parent_info, &local_parent_sp);
+                                       found_sp = mono_find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &parent_info, &local_parent_sp);
                                        parent_sp = found_sp ? &local_parent_sp : NULL;
                                        if (found_sp && parent_sp->next_len != 0)
                                                break;
@@ -5228,7 +5202,7 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                if (sp && sp->next_len > 0) {
                        SeqPoint* next = g_new(SeqPoint, sp->next_len);
 
-                       seq_point_init_next (info, *sp, next);
+                       mono_seq_point_init_next (info, *sp, next);
                        for (i = 0; i < sp->next_len; i++) {
                                next_sp = &next[i];
 
@@ -5241,7 +5215,7 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                if (parent_sp) {
                        SeqPoint* next = g_new(SeqPoint, parent_sp->next_len);
 
-                       seq_point_init_next (parent_info, *parent_sp, next);
+                       mono_seq_point_init_next (parent_info, *parent_sp, next);
                        for (i = 0; i < parent_sp->next_len; i++) {
                                next_sp = &next[i];
 
@@ -5275,7 +5249,7 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
                                        for (j = 0; j < jinfo->num_clauses; ++j) {
                                                MonoJitExceptionInfo *ei = &jinfo->clauses [j];
 
-                                               found_sp = find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp);
+                                               found_sp = mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp);
                                                sp = (found_sp)? &local_sp : NULL;
                                                if (sp) {
                                                        bp = set_breakpoint (frame->method, sp->il_offset, ss_req->req, NULL);
@@ -5386,7 +5360,7 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
                 * Find the seq point corresponding to the landing site ip, which is the first seq
                 * point after ip.
                 */
-               found_sp = find_next_seq_point_for_native_offset (frame.domain, frame.method, frame.native_offset, &info, &local_sp);
+               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);
@@ -5432,7 +5406,7 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
                if (frame) {
                        if (!method && frame->il_offset != -1) {
                                /* FIXME: Sort the table and use a binary search */
-                               found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
+                               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);
@@ -6561,12 +6535,21 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
                        return ERR_INVALID_ARGUMENT;
                }
                m = mono_object_get_virtual_method (this, m);
+               /* Transform this to the format the rest of the code expects it to be */
+               if (m->klass->valuetype) {
+                       this_buf = g_alloca (mono_class_instance_size (m->klass));
+                       memcpy (this_buf, mono_object_unbox (this), mono_class_instance_size (m->klass));
+               }
        } else if ((m->flags & METHOD_ATTRIBUTE_VIRTUAL) && !m->klass->valuetype && invoke->flags & INVOKE_FLAG_VIRTUAL) {
                if (!this) {
                        DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)GetCurrentThreadId ());
                        return ERR_INVALID_ARGUMENT;
                }
                m = mono_object_get_virtual_method (this, m);
+               if (m->klass->valuetype) {
+                       this_buf = g_alloca (mono_class_instance_size (m->klass));
+                       memcpy (this_buf, mono_object_unbox (this), mono_class_instance_size (m->klass));
+               }
        }
 
        DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this ? this->vtable->klass->name : "<null>");
@@ -6848,7 +6831,7 @@ get_source_files_for_type (MonoClass *klass)
                GPtrArray *source_file_list;
 
                if (minfo) {
-                       mono_debug_symfile_get_line_numbers_full (minfo, NULL, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                       mono_debug_get_seq_points (minfo, NULL, &source_file_list, NULL, NULL, NULL);
                        for (j = 0; j < source_file_list->len; ++j) {
                                sinfo = g_ptr_array_index (source_file_list, j);
                                for (i = 0; i < files->len; ++i)
@@ -8344,13 +8327,9 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                MonoDebugMethodInfo *minfo;
                char *source_file;
                int i, j, n_il_offsets;
-               int *il_offsets;
-               int *line_numbers;
-               int *column_numbers;
-               int *end_line_numbers;
-               int *end_column_numbers;
                int *source_files;
                GPtrArray *source_file_list;
+               MonoSymSeqPoint *sym_seq_points;
 
                header = mono_method_get_header (method);
                if (!header) {
@@ -8369,7 +8348,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                        break;
                }
 
-               mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, &n_il_offsets, &il_offsets, &line_numbers, &column_numbers, &source_files, &end_line_numbers, &end_column_numbers);
+               mono_debug_get_seq_points (minfo, &source_file, &source_file_list, &source_files, &sym_seq_points, &n_il_offsets);
                buffer_add_int (buf, header->code_size);
                if (CHECK_PROTOCOL_VERSION (2, 13)) {
                        buffer_add_int (buf, source_file_list->len);
@@ -8387,31 +8366,28 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                buffer_add_int (buf, n_il_offsets);
                DEBUG_PRINTF (10, "Line number table for method %s:\n", mono_method_full_name (method,  TRUE));
                for (i = 0; i < n_il_offsets; ++i) {
+                       MonoSymSeqPoint *sp = &sym_seq_points [i];
                        const char *srcfile = "";
 
                        if (source_files [i] != -1) {
                                MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, source_files [i]);
                                srcfile = sinfo->source_file;
                        }
-                       DEBUG_PRINTF (10, "IL%x -> %s:%d %d %d %d\n", il_offsets [i], srcfile, line_numbers [i], column_numbers ? column_numbers [i] : -1, end_line_numbers ? end_line_numbers [i] : -1, end_column_numbers ? end_column_numbers [i] : -1);
-                       buffer_add_int (buf, il_offsets [i]);
-                       buffer_add_int (buf, line_numbers [i]);
+                       DEBUG_PRINTF (10, "IL%x -> %s:%d %d %d %d\n", sp->il_offset, srcfile, sp->line, sp->column, sp->end_line, sp->end_column);
+                       buffer_add_int (buf, sp->il_offset);
+                       buffer_add_int (buf, sp->line);
                        if (CHECK_PROTOCOL_VERSION (2, 13))
                                buffer_add_int (buf, source_files [i]);
                        if (CHECK_PROTOCOL_VERSION (2, 19))
-                               buffer_add_int (buf, column_numbers ? column_numbers [i] : -1);
+                               buffer_add_int (buf, sp->column);
                        if (CHECK_PROTOCOL_VERSION (2, 32)) {
-                               buffer_add_int (buf, end_line_numbers ? end_line_numbers [i] : -1);
-                               buffer_add_int (buf, end_column_numbers ? end_column_numbers [i] : -1);
+                               buffer_add_int (buf, sp->end_line);
+                               buffer_add_int (buf, sp->end_column);
                        }
                }
                g_free (source_file);
-               g_free (il_offsets);
-               g_free (line_numbers);
-               g_free (column_numbers);
-               g_free (end_line_numbers);
-               g_free (end_column_numbers);
                g_free (source_files);
+               g_free (sym_seq_points);
                g_ptr_array_free (source_file_list, TRUE);
                mono_metadata_free_mh (header);
                break;
@@ -8445,50 +8421,73 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
        case CMD_METHOD_GET_LOCALS_INFO: {
                int i, j, num_locals;
                MonoDebugLocalsInfo *locals;
+               int *locals_map = NULL;
 
                header = mono_method_get_header (method);
                if (!header)
                        return ERR_INVALID_ARGUMENT;
 
-               buffer_add_int (buf, header->num_locals);
-
-               /* Types */
-               for (i = 0; i < header->num_locals; ++i)
-                       buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
-
-               /* Names */
                locals = mono_debug_lookup_locals (method);
-               if (locals)
-                       num_locals = locals->num_locals;
-               else
-                       num_locals = 0;
-               for (i = 0; i < header->num_locals; ++i) {
-                       for (j = 0; j < num_locals; ++j)
-                               if (locals->locals [j].index == i)
-                                       break;
-                       if (j < num_locals)
-                               buffer_add_string (buf, locals->locals [j].name);
-                       else
-                               buffer_add_string (buf, "");
-               }
-
-               /* Scopes */
-               for (i = 0; i < header->num_locals; ++i) {
-                       for (j = 0; j < num_locals; ++j)
-                               if (locals->locals [j].index == i)
-                                       break;
-                       if (j < num_locals && 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 {
+               if (!locals) {
+                       buffer_add_int (buf, header->num_locals);
+                       /* Types */
+                       for (i = 0; i < header->num_locals; ++i) {
+                               buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
+                       }
+                       /* Names */
+                       for (i = 0; i < header->num_locals; ++i) {
+                               char lname [128];
+                               sprintf (lname, "V_%d", i);
+                               buffer_add_string (buf, lname);
+                       }
+                       /* Scopes */
+                       for (i = 0; i < header->num_locals; ++i) {
                                buffer_add_int (buf, 0);
                                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]));
+                       }
+
+                       /* Names */
+                       for (i = 0; i < header->num_locals; ++i) {
+                               if (locals_map [i] != -1)
+                                       buffer_add_string (buf, locals->locals [locals_map [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);
+                                       }
+                               }
+                       }
                }
                mono_metadata_free_mh (header);
 
                if (locals)
-                       mono_debug_symfile_free_locals (locals);
+                       mono_debug_free_locals (locals);
+               g_free (locals_map);
 
                break;
        }
@@ -8864,7 +8863,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                if (tls->frame_count == 0 || tls->frames [0]->actual_method != method)
                        return ERR_INVALID_ARGUMENT;
 
-               found_sp = find_seq_point (domain, method, il_offset, &seq_points, &sp);
+               found_sp = mono_find_seq_point (domain, method, il_offset, &seq_points, &sp);
 
                g_assert (seq_points);
 
@@ -8951,7 +8950,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
        sig = mono_method_signature (frame->actual_method);
 
-       if (!get_seq_points (frame->domain, frame->actual_method))
+       if (!mono_get_seq_points (frame->domain, frame->actual_method))
                /*
                 * The method is probably from an aot image compiled without soft-debug, variables might be dead, etc.
                 */
@@ -8968,12 +8967,24 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                        if (pos < 0) {
                                pos = - pos - 1;
 
+                               DEBUG_PRINTF (4, "[dbg]   send arg %d.\n", pos);
+
                                g_assert (pos >= 0 && pos < jit->num_params);
 
                                add_var (buf, jit, sig->params [pos], &jit->params [pos], &frame->ctx, frame->domain, FALSE);
                        } else {
+                               MonoDebugLocalsInfo *locals;
+
+                               locals = mono_debug_lookup_locals (frame->method);
+                               if (locals) {
+                                       g_assert (pos < locals->num_locals);
+                                       pos = locals->locals [pos].index;
+                                       mono_debug_free_locals (locals);
+                               }
                                g_assert (pos >= 0 && pos < jit->num_locals);
 
+                               DEBUG_PRINTF (4, "[dbg]   send local %d.\n", pos);
+
                                add_var (buf, jit, header->locals [pos], &jit->locals [pos], &frame->ctx, frame->domain, FALSE);
                        }
                }
@@ -9017,6 +9028,14 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                t = sig->params [pos];
                                var = &jit->params [pos];
                        } else {
+                               MonoDebugLocalsInfo *locals;
+
+                               locals = mono_debug_lookup_locals (frame->method);
+                               if (locals) {
+                                       g_assert (pos < locals->num_locals);
+                                       pos = locals->locals [pos].index;
+                                       mono_debug_free_locals (locals);
+                               }
                                g_assert (pos >= 0 && pos < jit->num_locals);
 
                                t = header->locals [pos];