#include <mono/metadata/assembly.h>
#include <mono/metadata/runtime.h>
#include <mono/metadata/verify-internals.h>
+#include <mono/metadata/reflection-internals.h>
#include <mono/utils/mono-coop-mutex.h>
#include <mono/utils/mono-coop-semaphore.h>
#include <mono/utils/mono-error-internals.h>
}
}
- 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 */
static gint32 last_keepalive;
gint32 msecs;
+ MONO_PREPARE_BLOCKING;
+
do {
again:
res = recv (fd, (char *) buf + total, len - total, flags);
}
}
} while ((res > 0 && total < len) || (res == -1 && get_last_sock_error () == MONO_EINTR));
+
+ MONO_FINISH_BLOCKING;
+
return total;
}
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 {
{
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
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);
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) {
#else
shutdown (conn_fd, SHUT_RD);
shutdown (listen_fd, SHUT_RDWR);
+ MONO_PREPARE_BLOCKING;
close (listen_fd);
+ MONO_FINISH_BLOCKING;
#endif
}
/* 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;
if (!inited)
return;
- MONO_PREPARE_BLOCKING;
transport_close1 ();
- MONO_FINISH_BLOCKING;
/*
* Wait for the thread to exit.
} while (!debugger_thread_exited);
}
- MONO_PREPARE_BLOCKING;
transport_close2 ();
- MONO_FINISH_BLOCKING;
}
static void
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);
buffer_add_buffer (&buf, packets [i].data);
}
- MONO_PREPARE_BLOCKING;
res = transport_send (buf.buf, len);
- MONO_FINISH_BLOCKING;
buffer_free (&buf);
if (is_debugger_thread ())
DEBUG_PRINTF (2, "[dbg] send class [%s]\n", s);
else
- DEBUG_PRINTF (2, "[%p] send class [%s]\n", (gpointer)mono_native_thread_id_get (), s);
+ DEBUG_PRINTF (2, "[%p] send class [%s]\n", (gpointer) (gsize) mono_native_thread_id_get (), s);
g_free (s);
}
}
if (mono_native_thread_id_equals (mono_native_thread_id_get (), tid) || tls->terminated)
return;
- DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer)mono_native_thread_id_get (), (gpointer)tid);
+ DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer) (gsize) mono_native_thread_id_get (), (gpointer)tid);
/* This is _not_ equivalent to ves_icall_System_Threading_Thread_Abort () */
InterruptData interrupt_data = { 0 };
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)mono_native_thread_id_get (), (gpointer)tid);
+ DEBUG_PRINTF (1, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer) (gsize) mono_native_thread_id_get (), (gpointer)tid);
/*
* Attached thread which died without detaching.
*/
if (suspend_count - tls->resume_count > 0)
tls->suspending = TRUE;
- DEBUG_PRINTF (1, "[%p] Received single step event for suspending.\n", (gpointer)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Received single step event for suspending.\n", (gpointer) (gsize) mono_native_thread_id_get ());
if (suspend_count - tls->resume_count == 0) {
/*
* suspending is still active.
* FIXME: This slows down single threaded invokes.
*/
- DEBUG_PRINTF (1, "[%p] Ignored during single threaded invoke.\n", (gpointer)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Ignored during single threaded invoke.\n", (gpointer) (gsize) mono_native_thread_id_get ());
return;
}
suspend_count ++;
- DEBUG_PRINTF (1, "[%p] Suspending vm...\n", (gpointer)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Suspending vm...\n", (gpointer) (gsize) mono_native_thread_id_get ());
if (suspend_count == 1) {
// FIXME: Is it safe to call this inside the lock ?
g_assert (suspend_count > 0);
suspend_count --;
- DEBUG_PRINTF (1, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)mono_native_thread_id_get (), suspend_count);
+ DEBUG_PRINTF (1, "[%p] Resuming vm, suspend count=%d...\n", (gpointer) (gsize) mono_native_thread_id_get (), suspend_count);
if (suspend_count == 0) {
// FIXME: Is it safe to call this inside the lock ?
mono_coop_sem_post (&suspend_sem);
}
- DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)mono_native_thread_id_get ());
+ 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);
mono_coop_mutex_unlock (&suspend_mutex);
- DEBUG_PRINTF (1, "[%p] Resumed.\n", (gpointer)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Resumed.\n", (gpointer) (gsize) mono_native_thread_id_get ());
if (tls->pending_invoke) {
/* Save the original context */
vm_start_event_sent = TRUE;
}
- 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);
+ DEBUG_PRINTF (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer) (gsize) mono_native_thread_id_get (), nevents, event_to_string (event), ecount, suspend_policy);
switch (suspend_policy) {
case SUSPEND_POLICY_NONE:
/*
* 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)mono_native_thread_id_get (), sp->il_offset);
+ DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping over, continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), sp->il_offset);
return FALSE;
}
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)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get ());
return FALSE;
}
}
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)mono_native_thread_id_get (), sp->il_offset);
+ DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), sp->il_offset);
return FALSE;
}
}
loc = mono_debug_method_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)mono_native_thread_id_get (), sp->il_offset);
+ DEBUG_PRINTF (1, "[%p] No line number info for il offset %x, continuing single stepping.\n", (gpointer) (gsize) 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)mono_native_thread_id_get (), loc->row);
+ DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), loc->row);
hit = FALSE;
}
g_assert (found_sp);
- 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);
+ DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, [il=0x%x,native=0x%x].\n", (gpointer) (gsize) mono_native_thread_id_get (), method->name, ip, sp.il_offset, native_offset);
bp = NULL;
for (i = 0; i < breakpoints->len; ++i) {
// FIXME: This might not work on an altstack ?
tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id);
if (!tls)
- fprintf (stderr, "Thread %p is not attached to the JIT.\n", (gpointer)mono_native_thread_id_get ());
+ fprintf (stderr, "Thread %p is not attached to the JIT.\n", (gpointer) (gsize) mono_native_thread_id_get ());
g_assert (tls);
// FIXME: MonoContext usually doesn't include the fp registers, so these are
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)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);
+ DEBUG_PRINTF (1, "[%p] Single step event (depth=%s) at %s (%p)[0x%x], sp %p, last sp %p\n", (gpointer) (gsize) 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);
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)mono_native_thread_id_get (), name, name2);
+ DEBUG_PRINTF (1, "[%p] Expected value of type %s, got %s.\n", (gpointer) (gsize) mono_native_thread_id_get (), name, name2);
g_free (name);
g_free (name2);
return ERR_INVALID_ARGUMENT;
!(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)mono_native_thread_id_get (), name, type);
+ DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer) (gsize) mono_native_thread_id_get (), name, type);
g_free (name);
return ERR_INVALID_ARGUMENT;
}
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)mono_native_thread_id_get (), name, type);
+ DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer) (gsize) mono_native_thread_id_get (), name, type);
g_free (name);
return ERR_INVALID_ARGUMENT;
}
* 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)mono_native_thread_id_get (), mono_method_full_name (invoke->method, TRUE), this_arg ? this_arg->vtable->klass->name : "<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 : "<null>");
mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc);
g_assert_not_reached ();
}
/* 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)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Error: Static vtype method invoked with this argument.\n", (gpointer) (gsize) mono_native_thread_id_get ());
return ERR_INVALID_ARGUMENT;
}
memset (this_buf, 0, mono_class_instance_size (m->klass));
if (MONO_CLASS_IS_INTERFACE (m->klass)) {
if (!this_arg) {
- DEBUG_PRINTF (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer) (gsize) mono_native_thread_id_get ());
return ERR_INVALID_ARGUMENT;
}
m = mono_object_get_virtual_method (this_arg, m);
}
} 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)mono_native_thread_id_get ());
+ DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer) (gsize) mono_native_thread_id_get ());
return ERR_INVALID_ARGUMENT;
}
m = mono_object_get_virtual_method (this_arg, m);
}
}
- 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 : "<null>");
+ DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer) (gsize) mono_native_thread_id_get (), mono_method_full_name (m, TRUE), this_arg ? this_arg->vtable->klass->name : "<null>");
if (this_arg && this_arg->vtable->domain != domain)
NOT_IMPLEMENTED;
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)mono_native_thread_id_get (), 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) (gsize) 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);
tls->resume_count -= invoke->suspend_count;
}
- DEBUG_PRINTF (1, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer)mono_native_thread_id_get (), err, tls->resume_count);
+ DEBUG_PRINTF (1, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer) (gsize) mono_native_thread_id_get (), err, tls->resume_count);
/*
* Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE:
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);
}
}
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;
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);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
buffer_add_objid (buf, o);
break;
}
case CMD_TYPE_GET_INTERFACES: {
MonoClass *parent;
GHashTable *iface_hash = g_hash_table_new (NULL, NULL);
- MonoError error;
MonoClass *tclass, *iface;
GHashTableIter iter;
return err;
MonoClass *obj_type;
+ gboolean remote_obj = FALSE;
obj_type = obj->vtable->klass;
- if (mono_class_is_transparent_proxy (obj_type))
+ if (mono_class_is_transparent_proxy (obj_type)) {
obj_type = ((MonoTransparentProxy *)obj)->remote_class->proxy_class;
+ remote_obj = TRUE;
+ }
g_assert (obj_type);
buffer_add_value (buf, f->type, val, obj->vtable->domain);
g_free (val);
} else {
- buffer_add_value (buf, f->type, (guint8*)obj + f->offset, obj->vtable->domain);
+ guint8 *field_value = NULL;
+ void *field_storage = NULL;
+
+ if (remote_obj) {
+#ifndef DISABLE_REMOTING
+ field_value = mono_load_remote_field(obj, obj_type, f, &field_storage);
+#else
+ g_assert_not_reached ();
+#endif
+ } else
+ field_value = (guint8*)obj + f->offset;
+
+ buffer_add_value (buf, f->type, field_value, obj->vtable->domain);
}
}
break;
}
/* 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) {
gboolean no_reply;
gboolean attach_failed = FALSE;
- DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer)mono_native_thread_id_get ());
+ 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 ();
}
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) {
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;