#endif
}
- DEBUG (1, fprintf (log_file, "Listening on %s:%d (timeout=%d ms)...\n", host, port, agent_config.timeout));
-
if (agent_config.defer)
return;
+ DEBUG (1, fprintf (log_file, "Listening on %s:%d (timeout=%d ms)...\n", host, port, agent_config.timeout));
+
if (agent_config.timeout) {
fd_set readfds;
struct timeval tv;
res = select (sfd + 1, &readfds, NULL, NULL, &tv);
if (res == 0) {
fprintf (stderr, "debugger-agent: Timed out waiting to connect.\n");
- if (!agent_config.defer)
- exit (1);
+ exit (1);
}
}
mono_loader_unlock ();
}
-static AgentDomainInfo* get_agent_domain_info (MonoDomain *domain)
+static AgentDomainInfo*
+get_agent_domain_info (MonoDomain *domain)
{
AgentDomainInfo *info = NULL;
mono_loader_lock ();
- info = get_agent_domain_info (domain);
-
mono_domain_lock (domain);
+ info = get_agent_domain_info (domain);
+
if (info->val_to_id [type] == NULL)
info->val_to_id [type] = g_hash_table_new (mono_aligned_addr_hash, NULL);
if (ji) {
/* Running managed code, will be suspended by the single step code */
- DEBUG (1, printf ("[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)GetCurrentThreadId (), ji->method->name, mono_arch_ip_from_context (sigctx)));
+ DEBUG (1, fprintf (log_file, "[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)GetCurrentThreadId (), ji->method->name, mono_arch_ip_from_context (sigctx)));
return TRUE;
} else {
/*
// FIXME: printf is not signal safe, but this is only used during
// debugger debugging
if (sigctx)
- DEBUG (1, printf ("[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)GetCurrentThreadId (), mono_arch_ip_from_context (sigctx)));
+ DEBUG (1, fprintf (log_file, "[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)GetCurrentThreadId (), mono_arch_ip_from_context (sigctx)));
//save_thread_context (&ctx);
if (!tls->thread)
guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
MonoJitInfo *ji;
+ if (mono_loader_lock_is_owned_by_self ()) {
+ /*
+ * Shortcut for the check in suspend_current (). This speeds up processing
+ * when executing long running code inside the loader lock, i.e. assembly load
+ * hooks.
+ */
+ return;
+ }
+
if (debugger_thread_id == GetCurrentThreadId ())
return;
AgentDomainInfo *info = NULL;
mono_loader_lock ();
- info = get_agent_domain_info (domain);
mono_domain_lock (domain);
+ info = get_agent_domain_info (domain);
+
if (!g_hash_table_lookup (info->loaded_classes, klass)) {
type_load = TRUE;
g_hash_table_insert (info->loaded_classes, klass, klass);
}
if (!ss_req->bps) {
- DEBUG (1, printf ("[dbg] Turning on global single stepping.\n"));
+ DEBUG (1, fprintf (log_file, "[dbg] Turning on global single stepping.\n"));
ss_req->global = TRUE;
start_single_stepping ();
} else {
// FIXME: Multiple requests
if (ss_req) {
- DEBUG (0, printf ("Received a single step request while the previous one was still active.\n"));
+ DEBUG (0, fprintf (log_file, "Received a single step request while the previous one was still active.\n"));
return ERR_NOT_IMPLEMENTED;
}
- DEBUG (1, printf ("[dbg] Starting single step of thread %p (depth=%s).\n", thread, ss_depth_to_string (depth)));
+ DEBUG (1, fprintf (log_file, "[dbg] Starting single step of thread %p (depth=%s).\n", thread, ss_depth_to_string (depth)));
ss_req = g_new0 (SingleStepReq, 1);
ss_req->req = req;
* Invoke this method directly, currently only Environment.Exit () is supported.
*/
this = NULL;
- DEBUG (1, printf ("[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (invoke->method, TRUE), this ? this->vtable->klass->name : "<null>"));
+ DEBUG (1, fprintf (log_file, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (invoke->method, TRUE), this ? this->vtable->klass->name : "<null>"));
mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc);
g_assert_not_reached ();
}
else
this = NULL;
- DEBUG (1, printf ("[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this ? this->vtable->klass->name : "<null>"));
+ DEBUG (1, fprintf (log_file, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this ? this->vtable->klass->name : "<null>"));
if (this && this->vtable->domain != domain)
NOT_IMPLEMENTED;
} else if (MONO_TYPE_IS_REFERENCE (sig->ret)) {
buffer_add_value (buf, sig->ret, &res, domain);
} else if (mono_class_from_mono_type (sig->ret)->valuetype) {
- g_assert (res);
- buffer_add_value (buf, sig->ret, mono_object_unbox (res), domain);
+ if (mono_class_is_nullable (mono_class_from_mono_type (sig->ret))) {
+ if (!res)
+ buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &res, domain);
+ else
+ buffer_add_value (buf, sig->ret, mono_object_unbox (res), domain);
+ } else {
+ g_assert (res);
+ buffer_add_value (buf, sig->ret, mono_object_unbox (res), domain);
+ }
} else {
NOT_IMPLEMENTED;
}
tls->resume_count -= invoke->suspend_count;
}
- DEBUG (1, printf ("[%p] Invoke finished, resume_count = %d.\n", (gpointer)GetCurrentThreadId (), tls->resume_count));
+ DEBUG (1, fprintf (log_file, "[%p] Invoke finished, resume_count = %d.\n", (gpointer)GetCurrentThreadId (), tls->resume_count));
/*
* Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE:
wait_for_suspend ();
env_class = mono_class_from_name (mono_defaults.corlib, "System", "Environment");
- g_assert (env_class);
- exit_method = mono_class_get_method_from_name (env_class, "Exit", 1);
- g_assert (exit_method);
+ if (env_class)
+ exit_method = mono_class_get_method_from_name (env_class, "Exit", 1);
mono_loader_lock ();
thread = mono_g_hash_table_find (tid_to_thread, is_really_suspended, NULL);
mono_loader_unlock ();
- if (thread) {
+ if (thread && exit_method) {
mono_loader_lock ();
tls = mono_g_hash_table_lookup (thread_to_tls, thread);
mono_loader_unlock ();
mono_cond_signal (&debugger_thread_exited_cond);
mono_mutex_unlock (&debugger_thread_exited_mutex);
- DEBUG (1, printf ("[dbg] Debugger thread exited.\n"));
+ DEBUG (1, fprintf (log_file, "[dbg] Debugger thread exited.\n"));
if (!attach_failed && command_set == CMD_SET_VM && command == CMD_VM_DISPOSE && !(vm_death_event_sent || mono_runtime_is_shutting_down ())) {
DEBUG (2, fprintf (log_file, "[dbg] Detached - restarting clean debugger thread.\n"));