X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdebugger-agent.c;h=140fbfb689b1f89ea0ef61570ed56b0c51bf9c01;hb=4ef4438ad9e8cb0f79b9e472b38dbd0cd848d812;hp=b527d51d54499f2f99c7cd9c42bc6876b98dc12a;hpb=0d787e165d49fbf9334d7a22b504d34e27afdfe8;p=mono.git diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index b527d51d544..140fbfb689b 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -229,7 +230,7 @@ typedef struct { gboolean abort_requested; /* - * The current mono_runtime_invoke invocation. + * The current mono_runtime_invoke_checked invocation. */ InvokeData *invoke; @@ -1078,9 +1079,7 @@ finish_agent_init (gboolean on_startup) } } - MONO_PREPARE_BLOCKING; transport_connect (agent_config.address); - MONO_FINISH_BLOCKING; if (!on_startup) { /* Do some which is usually done after sending the VMStart () event */ @@ -1123,6 +1122,8 @@ socket_transport_recv (void *buf, int len) static gint32 last_keepalive; gint32 msecs; + MONO_PREPARE_BLOCKING; + do { again: res = recv (fd, (char *) buf + total, len - total, flags); @@ -1146,6 +1147,9 @@ socket_transport_recv (void *buf, int len) } } } while ((res > 0 && total < len) || (res == -1 && get_last_sock_error () == MONO_EINTR)); + + MONO_FINISH_BLOCKING; + return total; } @@ -1168,7 +1172,10 @@ set_keepalive (void) static int socket_transport_accept (int socket_fd) { + MONO_PREPARE_BLOCKING; conn_fd = accept (socket_fd, NULL, NULL); + MONO_FINISH_BLOCKING; + if (conn_fd == -1) { fprintf (stderr, "debugger-agent: Unable to listen on %d\n", socket_fd); } else { @@ -1183,9 +1190,14 @@ socket_transport_send (void *data, int len) { int res; + MONO_PREPARE_BLOCKING; + do { res = send (conn_fd, data, len, 0); } while (res == -1 && get_last_sock_error () == MONO_EINTR); + + MONO_FINISH_BLOCKING; + if (res != len) return FALSE; else @@ -1302,16 +1314,18 @@ socket_transport_connect (const char *address) tv.tv_usec = agent_config.timeout * 1000; FD_ZERO (&readfds); FD_SET (sfd, &readfds); + + MONO_PREPARE_BLOCKING; res = select (sfd + 1, &readfds, NULL, NULL, &tv); + MONO_FINISH_BLOCKING; + if (res == 0) { fprintf (stderr, "debugger-agent: Timed out waiting to connect.\n"); exit (1); } } - MONO_PREPARE_BLOCKING; conn_fd = socket_transport_accept (sfd); - MONO_FINISH_BLOCKING; if (conn_fd == -1) exit (1); @@ -1330,10 +1344,16 @@ socket_transport_connect (const char *address) if (sfd == -1) continue; - if (connect (sfd, &sockaddr.addr, sock_len) != -1) + MONO_PREPARE_BLOCKING; + res = connect (sfd, &sockaddr.addr, sock_len); + MONO_FINISH_BLOCKING; + + if (res != -1) break; /* Success */ + MONO_PREPARE_BLOCKING; close (sfd); + MONO_FINISH_BLOCKING; } if (rp == 0) { @@ -1364,7 +1384,9 @@ socket_transport_close1 (void) #else shutdown (conn_fd, SHUT_RD); shutdown (listen_fd, SHUT_RDWR); + MONO_PREPARE_BLOCKING; close (listen_fd); + MONO_FINISH_BLOCKING; #endif } @@ -1530,19 +1552,15 @@ transport_handshake (void) /* Write handshake message */ sprintf (handshake_msg, "DWP-Handshake"); - /* Must use try blocking as this can nest into code that runs blocking */ - MONO_PREPARE_BLOCKING; + do { res = transport_send (handshake_msg, strlen (handshake_msg)); } while (res == -1 && get_last_sock_error () == MONO_EINTR); - MONO_FINISH_BLOCKING; g_assert (res != -1); /* Read answer */ - MONO_PREPARE_BLOCKING; res = transport_recv (buf, strlen (handshake_msg)); - MONO_FINISH_BLOCKING; if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg)) != 0)) { fprintf (stderr, "debugger-agent: DWP handshake failed.\n"); return FALSE; @@ -1585,9 +1603,7 @@ stop_debugger_thread (void) if (!inited) return; - MONO_PREPARE_BLOCKING; transport_close1 (); - MONO_FINISH_BLOCKING; /* * Wait for the thread to exit. @@ -1604,9 +1620,7 @@ stop_debugger_thread (void) } while (!debugger_thread_exited); } - MONO_PREPARE_BLOCKING; transport_close2 (); - MONO_FINISH_BLOCKING; } static void @@ -1800,9 +1814,7 @@ send_packet (int command_set, int command, Buffer *data) buffer_add_byte (&buf, command); memcpy (buf.buf + 11, data->buf, data->p - data->buf); - MONO_PREPARE_BLOCKING; res = transport_send (buf.buf, len); - MONO_FINISH_BLOCKING; buffer_free (&buf); @@ -1829,9 +1841,7 @@ send_reply_packets (int npackets, ReplyPacket *packets) buffer_add_buffer (&buf, packets [i].data); } - MONO_PREPARE_BLOCKING; res = transport_send (buf.buf, len); - MONO_FINISH_BLOCKING; buffer_free (&buf); @@ -3313,25 +3323,23 @@ static void init_jit_info_dbg_attrs (MonoJitInfo *ji) { static MonoClass *hidden_klass, *step_through_klass, *non_user_klass; + MonoError error; MonoCustomAttrInfo *ainfo; if (ji->dbg_attrs_inited) return; - if (!hidden_klass) { - hidden_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute"); - g_assert (hidden_klass); - } - if (!step_through_klass) { - step_through_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute"); - g_assert (step_through_klass); - } - if (!non_user_klass) { - non_user_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute"); - g_assert (non_user_klass); - } + if (!hidden_klass) + hidden_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute"); + + if (!step_through_klass) + step_through_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute"); - ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji)); + if (!non_user_klass) + non_user_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute"); + + ainfo = mono_custom_attrs_from_method_checked (jinfo_get_method (ji), &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error? */ if (ainfo) { if (mono_custom_attrs_has_attr (ainfo, hidden_klass)) ji->dbg_hidden = TRUE; @@ -3342,7 +3350,8 @@ init_jit_info_dbg_attrs (MonoJitInfo *ji) mono_custom_attrs_free (ainfo); } - ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass); + ainfo = mono_custom_attrs_from_class_checked (jinfo_get_method (ji)->klass, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error? */ if (ainfo) { if (mono_custom_attrs_has_attr (ainfo, step_through_klass)) ji->dbg_step_through = TRUE; @@ -6451,6 +6460,7 @@ add_thread (gpointer key, gpointer value, gpointer user_data) static ErrorCode do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 *p, guint8 **endp) { + MonoError error; guint8 *end = invoke->endp; MonoMethod *m; int i, nargs; @@ -6472,7 +6482,10 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 */ this_arg = NULL; DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer) (gsize) 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); + + mono_runtime_try_invoke (invoke->method, NULL, invoke->args, &exc, &error); + mono_error_assert_ok (&error); + g_assert_not_reached (); } @@ -6549,8 +6562,11 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 if (!strcmp (m->name, ".ctor")) { if (m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) return ERR_INVALID_ARGUMENT; - else - this_arg = mono_object_new (domain, m->klass); + else { + MonoError error; + this_arg = mono_object_new_checked (domain, m->klass, &error); + mono_error_assert_ok (&error); + } } else { return ERR_INVALID_ARGUMENT; } @@ -6617,10 +6633,12 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 #endif mono_stopwatch_start (&watch); - if (m->klass->valuetype) - res = mono_runtime_invoke (m, this_buf, args, &exc); - else - res = mono_runtime_invoke (m, this_arg, args, &exc); + res = mono_runtime_try_invoke (m, m->klass->valuetype ? (gpointer) this_buf : (gpointer) this_arg, args, &exc, &error); + if (exc == NULL && !mono_error_ok (&error)) { + exc = (MonoObject*) mono_error_convert_to_exception (&error); + } else { + mono_error_cleanup (&error); /* FIXME report error */ + } mono_stopwatch_stop (&watch); DEBUG_PRINTF (1, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer) (gsize) mono_native_thread_id_get (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch)); if (exc) { @@ -6776,7 +6794,7 @@ invoke_method (void) * Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE: * * It is possible that ves_icall_System_Threading_Thread_Abort () was called - * after the mono_runtime_invoke() already returned, but it doesn't matter + * after the mono_runtime_invoke_checked() already returned, but it doesn't matter * because we reset the abort here. */ @@ -6938,7 +6956,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) wait_for_suspend (); #ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT - env_class = mono_class_from_name (mono_defaults.corlib, "System", "Environment"); + env_class = mono_class_try_load_from_name (mono_defaults.corlib, "System", "Environment"); if (env_class) exit_method = mono_class_get_method_from_name (env_class, "Exit", 1); #endif @@ -7071,7 +7089,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) } /* - * Check whether we're still inside the mono_runtime_invoke() and that it's + * Check whether we're still inside the mono_runtime_invoke_checked() and that it's * actually the correct invocation. * * Careful, we do not stop the thread that's doing the invocation, so we can't @@ -7562,6 +7580,7 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; } case CMD_APPDOMAIN_CREATE_BOXED_VALUE: { + MonoError error; MonoClass *klass; MonoDomain *domain2; MonoObject *o; @@ -7576,7 +7595,8 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) // FIXME: g_assert (domain == domain2); - o = mono_object_new (domain, klass); + o = mono_object_new_checked (domain, klass, &error); + mono_error_assert_ok (&error); err = decode_value (&klass->byval_arg, domain, (guint8 *)mono_object_unbox (o), p, &p, end); if (err != ERR_NONE) @@ -7619,7 +7639,10 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (token == 0) { buffer_add_id (buf, 0); } else { - m = mono_get_method (ass->image, token, NULL); + MonoError error; + m = mono_get_method_checked (ass->image, token, NULL, NULL, &error); + if (!m) + mono_error_cleanup (&error); /* FIXME don't swallow the error */ buffer_add_methodid (buf, domain, m); } } @@ -7630,7 +7653,12 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; } case CMD_ASSEMBLY_GET_OBJECT: { - MonoObject *o = (MonoObject*)mono_assembly_get_object (domain, ass); + MonoError error; + MonoObject *o = (MonoObject*)mono_assembly_get_object_checked (domain, ass, &error); + if (!o) { + mono_error_cleanup (&error); /* FIXME don't swallow the error */ + return ERR_INVALID_OBJECT; + } buffer_add_objid (buf, o); break; } @@ -7849,6 +7877,7 @@ collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error) static ErrorCode type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint8 *p, guint8 *end, Buffer *buf) { + MonoError error; MonoClass *nested; MonoType *type; gpointer iter; @@ -8004,7 +8033,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint if (err != ERR_NONE) return err; - cinfo = mono_custom_attrs_from_class (klass); + cinfo = mono_custom_attrs_from_class_checked (klass, &error); + if (!is_ok (&error)) { + mono_error_cleanup (&error); /* FIXME don't swallow the error message */ + return ERR_LOADER_ERROR; + } err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo); if (err != ERR_NONE) @@ -8023,7 +8056,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint if (err != ERR_NONE) return err; - cinfo = mono_custom_attrs_from_field (klass, field); + cinfo = mono_custom_attrs_from_field_checked (klass, field, &error); + if (!is_ok (&error)) { + mono_error_cleanup (&error); /* FIXME don't swallow the error message */ + return ERR_LOADER_ERROR; + } err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo); if (err != ERR_NONE) @@ -8042,7 +8079,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint if (err != ERR_NONE) return err; - cinfo = mono_custom_attrs_from_property (klass, prop); + cinfo = mono_custom_attrs_from_property_checked (klass, prop, &error); + if (!is_ok (&error)) { + mono_error_cleanup (&error); /* FIXME don't swallow the error message */ + return ERR_LOADER_ERROR; + } err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo); if (err != ERR_NONE) @@ -8153,7 +8194,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint break; } case CMD_TYPE_GET_OBJECT: { - MonoObject *o = (MonoObject*)mono_type_get_object (domain, &klass->byval_arg); + MonoObject *o = (MonoObject*)mono_type_get_object_checked (domain, &klass->byval_arg, &error); + if (!mono_error_ok (&error)) { + mono_error_cleanup (&error); + return ERR_INVALID_OBJECT; + } buffer_add_objid (buf, o); break; } @@ -8212,7 +8257,6 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint case CMD_TYPE_GET_INTERFACES: { MonoClass *parent; GHashTable *iface_hash = g_hash_table_new (NULL, NULL); - MonoError error; MonoClass *tclass, *iface; GHashTableIter iter; @@ -8277,9 +8321,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint break; } case CMD_TYPE_CREATE_INSTANCE: { + MonoError error; MonoObject *obj; - obj = mono_object_new (domain, klass); + obj = mono_object_new_checked (domain, klass, &error); + mono_error_assert_ok (&error); buffer_add_objid (buf, obj); break; } @@ -8329,6 +8375,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g break; } case CMD_METHOD_GET_DEBUG_INFO: { + MonoError error; MonoDebugMethodInfo *minfo; char *source_file; int i, j, n_il_offsets; @@ -8336,8 +8383,9 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g GPtrArray *source_file_list; MonoSymSeqPoint *sym_seq_points; - header = mono_method_get_header (method); + header = mono_method_get_header_checked (method, &error); if (!header) { + mono_error_cleanup (&error); /* FIXME don't swallow the error */ buffer_add_int (buf, 0); buffer_add_string (buf, ""); buffer_add_int (buf, 0); @@ -8424,13 +8472,16 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g break; } case CMD_METHOD_GET_LOCALS_INFO: { + MonoError error; int i, num_locals; MonoDebugLocalsInfo *locals; int *locals_map = NULL; - header = mono_method_get_header (method); - if (!header) + header = mono_method_get_header_checked (method, &error); + if (!header) { + mono_error_cleanup (&error); /* FIXME don't swallow the error */ return ERR_INVALID_ARGUMENT; + } locals = mono_debug_lookup_locals (method); if (!locals) { @@ -8551,10 +8602,12 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g } break; case CMD_METHOD_GET_BODY: { + MonoError error; int i; - header = mono_method_get_header (method); + header = mono_method_get_header_checked (method, &error); if (!header) { + mono_error_cleanup (&error); /* FIXME don't swallow the error */ buffer_add_int (buf, 0); if (CHECK_PROTOCOL_VERSION (2, 18)) @@ -8653,6 +8706,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g break; } case CMD_METHOD_GET_CATTRS: { + MonoError error; MonoClass *attr_klass; MonoCustomAttrInfo *cinfo; @@ -8661,7 +8715,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g if (err != ERR_NONE) return err; - cinfo = mono_custom_attrs_from_method (method); + cinfo = mono_custom_attrs_from_method_checked (method, &error); + if (!is_ok (&error)) { + mono_error_cleanup (&error); /* FIXME don't swallow the error message */ + return ERR_LOADER_ERROR; + } err = buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo); if (err != ERR_NONE) @@ -8948,8 +9006,10 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) switch (command) { case CMD_STACK_FRAME_GET_VALUES: { + MonoError error; len = decode_int (p, &p, end); - header = mono_method_get_header (frame->actual_method); + header = mono_method_get_header_checked (frame->actual_method, &error); + mono_error_assert_ok (&error); /* FIXME report error */ for (i = 0; i < len; ++i) { pos = decode_int (p, &p, end); @@ -9000,12 +9060,14 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; } case CMD_STACK_FRAME_SET_VALUES: { + MonoError error; guint8 *val_buf; MonoType *t; MonoDebugVarInfo *var; len = decode_int (p, &p, end); - header = mono_method_get_header (frame->actual_method); + header = mono_method_get_header_checked (frame->actual_method, &error); + mono_error_assert_ok (&error); /* FIXME report error */ for (i = 0; i < len; ++i) { pos = decode_int (p, &p, end); @@ -9564,9 +9626,7 @@ wait_for_attach (void) } /* Block and wait for client connection */ - MONO_PREPARE_BLOCKING; conn_fd = socket_transport_accept (listen_fd); - MONO_FINISH_BLOCKING; DEBUG_PRINTF (1, "Accepted connection on %d\n", conn_fd); if (conn_fd == -1) { @@ -9604,12 +9664,13 @@ debugger_thread (void *arg) ErrorCode err; gboolean no_reply; gboolean attach_failed = FALSE; + gpointer attach_cookie, attach_dummy; DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer) (gsize) mono_native_thread_id_get ()); debugger_thread_id = mono_native_thread_id_get (); - mono_jit_thread_attach (mono_get_root_domain ()); + attach_cookie = mono_jit_thread_attach (mono_get_root_domain (), &attach_dummy); mono_thread_internal_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE; @@ -9626,9 +9687,7 @@ debugger_thread (void *arg) } while (!attach_failed) { - MONO_PREPARE_BLOCKING; res = transport_recv (header, HEADER_LENGTH); - MONO_FINISH_BLOCKING; /* This will break if the socket is closed during shutdown too */ if (res != HEADER_LENGTH) { @@ -9663,9 +9722,7 @@ debugger_thread (void *arg) data = (guint8 *)g_malloc (len - HEADER_LENGTH); if (len - HEADER_LENGTH > 0) { - MONO_PREPARE_BLOCKING; res = transport_recv (data, len - HEADER_LENGTH); - MONO_FINISH_BLOCKING; if (res != len - HEADER_LENGTH) { DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH); break; @@ -9766,7 +9823,9 @@ debugger_thread (void *arg) DEBUG_PRINTF (2, "[dbg] Detached - restarting clean debugger thread.\n"); start_debugger_thread (); } - + + mono_jit_thread_detach (attach_cookie, &attach_dummy); + return 0; }