#define HEADER_LENGTH 11
#define MAJOR_VERSION 2
-#define MINOR_VERSION 42
+#define MINOR_VERSION 44
typedef enum {
CMD_SET_VM = 1,
CMD_STACK_FRAME_GET_THIS = 2,
CMD_STACK_FRAME_SET_VALUES = 3,
CMD_STACK_FRAME_GET_DOMAIN = 4,
+ CMD_STACK_FRAME_SET_THIS = 5,
} CmdStackFrame;
typedef enum {
static gboolean transport_handshake (void);
static void register_transport (DebuggerTransport *trans);
-static guint32 WINAPI debugger_thread (void *arg);
+static gsize WINAPI debugger_thread (void *arg);
static void runtime_initialized (MonoProfiler *prof);
static void
start_debugger_thread (void)
{
- MonoThreadParm tp;
-
- tp.priority = 0;
- tp.stack_size = 0;
- tp.creation_flags = 0;
- debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, &tp, NULL);
+ debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, 0, NULL);
g_assert (debugger_thread_handle);
}
static void
resume_vm (void)
{
- int err;
-
g_assert (is_debugger_thread ());
mono_loader_lock ();
}
/* Signal this even when suspend_count > 0, since some threads might have resume_count > 0 */
- err = mono_coop_cond_broadcast (&suspend_cond);
- g_assert (err == 0);
+ mono_coop_cond_broadcast (&suspend_cond);
mono_coop_mutex_unlock (&suspend_mutex);
//g_assert (err == 0);
static void
resume_thread (MonoInternalThread *thread)
{
- int err;
DebuggerTlsData *tls;
g_assert (is_debugger_thread ());
* Signal suspend_count without decreasing suspend_count, the threads will wake up
* but only the one whose resume_count field is > 0 will be resumed.
*/
- err = mono_coop_cond_broadcast (&suspend_cond);
- g_assert (err == 0);
+ mono_coop_cond_broadcast (&suspend_cond);
mono_coop_mutex_unlock (&suspend_mutex);
//g_assert (err == 0);
suspend_current (void)
{
DebuggerTlsData *tls;
- int err;
g_assert (!is_debugger_thread ());
DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer) (gsize) mono_native_thread_id_get ());
while (suspend_count - tls->resume_count > 0) {
- err = mono_coop_cond_wait (&suspend_cond, &suspend_mutex);
- g_assert (err == 0);
+ mono_coop_cond_wait (&suspend_cond, &suspend_mutex);
}
tls->suspended = FALSE;
MonoError oerror;
/* Might be AOTed code */
+ mono_class_init (method->klass);
code = mono_aot_get_method_checked (domain, method, &oerror);
g_assert (code);
mono_error_assert_ok (&oerror);
locals = mono_debug_lookup_locals (method);
if (!locals) {
+ if (CHECK_PROTOCOL_VERSION (2, 43)) {
+ /* Scopes */
+ buffer_add_int (buf, 1);
+ buffer_add_int (buf, 0);
+ buffer_add_int (buf, header->code_size);
+ }
buffer_add_int (buf, header->num_locals);
/* Types */
for (i = 0; i < header->num_locals; ++i) {
buffer_add_int (buf, header->code_size);
}
} else {
+ if (CHECK_PROTOCOL_VERSION (2, 43)) {
+ /* Scopes */
+ buffer_add_int (buf, locals->num_blocks);
+ int last_start = 0;
+ for (i = 0; i < locals->num_blocks; ++i) {
+ buffer_add_int (buf, locals->code_blocks [i].start_offset - last_start);
+ buffer_add_int (buf, locals->code_blocks [i].end_offset - locals->code_blocks [i].start_offset);
+ last_start = locals->code_blocks [i].start_offset;
+ }
+ }
+
num_locals = locals->num_locals;
buffer_add_int (buf, num_locals);
sig = mono_method_signature (frame->actual_method);
- if (!mono_get_seq_points (frame->domain, frame->actual_method))
+ if (!jit->has_var_info || !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.
*/
buffer_add_domainid (buf, frame->domain);
break;
}
+ case CMD_STACK_FRAME_SET_THIS: {
+ guint8 *val_buf;
+ MonoType *t;
+ MonoDebugVarInfo *var;
+
+ t = &frame->actual_method->klass->byval_arg;
+ /* Checked by the sender */
+ g_assert (MONO_TYPE_ISSTRUCT (t));
+ var = jit->this_var;
+ g_assert (var);
+
+ val_buf = (guint8 *)g_alloca (mono_class_instance_size (mono_class_from_mono_type (t)));
+ err = decode_value (t, frame->domain, val_buf, p, &p, end);
+ if (err != ERR_NONE)
+ return err;
+
+ set_var (&frame->actual_method->klass->this_arg, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
+ break;
+ }
default:
return ERR_NOT_IMPLEMENTED;
}
g_free (val);
} else {
guint8 *field_value = NULL;
- void *field_storage = NULL;
if (remote_obj) {
#ifndef DISABLE_REMOTING
+ void *field_storage = NULL;
field_value = mono_load_remote_field_checked(obj, obj_type, f, &field_storage, &error);
if (!is_ok (&error)) {
mono_error_cleanup (&error); /* FIXME report the error */
"GET_THIS",
"SET_VALUES",
"GET_DOMAIN",
+ "SET_THIS"
};
static const char* array_cmds_str[] = {
* This thread handles communication with the debugger client using a JDWP
* like protocol.
*/
-static guint32 WINAPI
+static gsize WINAPI
debugger_thread (void *arg)
{
MonoError error;
thread->internal_thread->state |= ThreadState_Background;
thread->internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
- mono_set_is_debugger_attached (TRUE);
-
if (agent_config.defer) {
if (!wait_for_attach ()) {
DEBUG_PRINTF (1, "[dbg] Can't attach, aborting debugger thread.\n");
attach_failed = TRUE; // Don't abort process when we can't listen
} else {
+ mono_set_is_debugger_attached (TRUE);
/* Send start event to client */
process_profiler_event (EVENT_KIND_VM_START, mono_thread_get_main ());
}
+ } else {
+ mono_set_is_debugger_attached (TRUE);
}
while (!attach_failed) {