-/*
- * debugger-agent.c: Soft Debugger back-end module
+/**
+ * \file
+ * Soft Debugger back-end module
*
* Author:
* Zoltan Varga (vargaz@gmail.com)
#endif
#include <mono/metadata/mono-debug.h>
-#include <mono/metadata/mono-debug-debugger.h>
-#include <mono/metadata/debug-mono-symfile.h>
+#include <mono/metadata/debug-internals.h>
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/threads-types.h>
static inline gboolean
is_debugger_thread (void)
{
- return mono_native_thread_id_equals (mono_native_thread_id_get (), debugger_thread_id);
+ MonoInternalThread *internal;
+
+ internal = mono_thread_internal_current ();
+ if (!internal)
+ return FALSE;
+
+ return internal->debugger_thread;
}
static int
if (pos == NULL || pos == address)
return 1;
- *host = (char *)g_malloc (pos - address + 1);
- strncpy (*host, address, pos - address);
- (*host) [pos - address] = '\0';
+ size_t len = pos - address;
+ *host = (char *)g_malloc (len + 1);
+ memcpy (*host, address, len);
+ (*host) [len] = '\0';
*port = atoi (pos + 1);
char **args, **ptr;
char *host;
int port;
- const char *extra;
+ char *extra;
#ifndef MONO_ARCH_SOFT_DEBUG_SUPPORTED
fprintf (stderr, "--debugger-agent is not supported on this platform.\n");
#endif
extra = g_getenv ("MONO_SDB_ENV_OPTIONS");
- if (extra)
+ if (extra) {
options = g_strdup_printf ("%s,%s", options, extra);
+ g_free (extra);
+ }
agent_config.enabled = TRUE;
agent_config.suspend = TRUE;
/* Needed by the hash_table_new_type () call below */
mono_gc_base_init ();
- thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
- MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
+ thread_to_tls = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread table");
- MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread table");
tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread object table");
- MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread object table");
pending_assembly_loads = g_ptr_array_new ();
domains = g_hash_table_new (mono_aligned_addr_hash, NULL);
static void
start_debugger_thread (void)
{
- debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, NULL, NULL);
+ MonoError error;
+ MonoInternalThread *thread;
+
+ thread = mono_thread_create_internal (mono_get_root_domain (), debugger_thread, NULL, MONO_THREAD_CREATE_FLAGS_DEBUGGER, &error);
+ mono_error_assert_ok (&error);
+
+ debugger_thread_handle = mono_threads_open_thread_handle (thread->handle);
g_assert (debugger_thread_handle);
}
{
objrefs = g_hash_table_new_full (NULL, NULL, NULL, free_objref);
obj_to_objref = g_hash_table_new (NULL, NULL);
- suspended_objs = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
- MONO_GC_REGISTER_ROOT_FIXED (suspended_objs, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
+ suspended_objs = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
}
static void
DebuggerTlsData *tls = (DebuggerTlsData *)value;
MonoNativeThreadId tid = MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid);
- if (mono_native_thread_id_equals (mono_native_thread_id_get (), tid) || tls->terminated)
+ if (mono_thread_internal_is_current (thread) || tls->terminated)
return;
DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer) (gsize) mono_native_thread_id_get (), (gpointer)tid);
{
DebuggerTlsData *tls = (DebuggerTlsData *)value;
- if (!tls->suspended && !tls->terminated)
+ if (!tls->suspended && !tls->terminated && !mono_thread_internal_is_current (tls->thread))
*(int*)user_data = *(int*)user_data + 1;
}
static void
emit_thread_start (gpointer key, gpointer value, gpointer user_data)
{
- if (!mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (GPOINTER_TO_UINT (key)), debugger_thread_id))
- process_profiler_event (EVENT_KIND_THREAD_START, value);
+ g_assert (!mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (GPOINTER_TO_UINT (key)), debugger_thread_id));
+ process_profiler_event (EVENT_KIND_THREAD_START, value);
}
/*
MonoInternalThread *old_thread;
DebuggerTlsData *tls;
- if (mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (tid), debugger_thread_id))
+ if (is_debugger_thread ())
return;
g_assert (mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (tid), MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid)));
if (thread) {
DEBUG_PRINTF (1, "[%p] Thread terminated, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls);
- if (mono_native_thread_id_equals (mono_native_thread_id_get (), MONO_UINT_TO_NATIVE_THREAD_ID (tid))
- && !mono_native_tls_get_value (debugger_tls_id)
+ if (mono_thread_internal_is_current (thread) && !mono_native_tls_get_value (debugger_tls_id)
) {
/*
* This can happen on darwin since we deregister threads using pthread dtors.
gboolean it_has_sp = FALSE;
if (error)
- mono_error_init (error);
+ error_init (error);
mono_seq_point_iterator_init (&it, seq_points);
while (mono_seq_point_iterator_next (&it)) {
MonoJitInfo *ji;
if (error)
- mono_error_init (error);
+ error_init (error);
code = mono_jit_find_compiled_method_with_jit_info (domain, method, &ji);
if (!code) {
int i;
if (error)
- mono_error_init (error);
+ error_init (error);
// FIXME:
// - suspend/resume the vm to prevent code patching problems
return get_objid (get_this (frame));
}
-static MonoMethod* set_notification_method_cache = NULL;
-
static MonoMethod*
-get_set_notification_method ()
+get_set_notification_method (MonoClass* async_builder_class)
{
- if(set_notification_method_cache != NULL)
- return set_notification_method_cache;
MonoError error;
- MonoClass* async_builder_class = mono_class_load_from_name (mono_defaults.corlib, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
GPtrArray* array = mono_class_get_methods_by_name (async_builder_class, "SetNotificationForWaitCompletion", 0x24, FALSE, FALSE, &error);
mono_error_assert_ok (&error);
g_assert (array->len == 1);
- set_notification_method_cache = (MonoMethod *)g_ptr_array_index (array, 0);
+ MonoMethod* set_notification_method = (MonoMethod *)g_ptr_array_index (array, 0);
g_ptr_array_free (array, TRUE);
- return set_notification_method_cache;
+ return set_notification_method;
}
static void
void* args [1];
gboolean arg = TRUE;
args [0] = &arg;
- mono_runtime_invoke_checked (get_set_notification_method(), mono_object_unbox (builder), args, &error);
+ mono_runtime_invoke_checked (get_set_notification_method (builder->vtable->klass), mono_object_unbox (builder), args, &error);
mono_error_assert_ok (&error);
mono_field_set_value (obj, builder_field, mono_object_unbox (builder));
}
case CMD_APPDOMAIN_CREATE_STRING: {
char *s;
MonoString *o;
+ MonoError error;
domain = decode_domainid (p, &p, end, NULL, &err);
if (err != ERR_NONE)
return err;
s = decode_string (p, &p, end);
- o = mono_string_new (domain, s);
+ o = mono_string_new_checked (domain, s, &error);
+ if (!is_ok (&error)) {
+ DEBUG_PRINTF (1, "[dbg] Failed to allocate String object '%s': %s\n", s, mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ return ERR_INVALID_OBJECT;
+ }
buffer_add_objid (buf, (MonoObject*)o);
break;
}
{
HANDLE_FUNCTION_ENTER();
ErrorCode err = ERR_NONE;
- mono_error_init (error);
+ error_init (error);
MonoReflectionAssemblyHandle o = mono_assembly_get_object_handle (domain, ass, error);
if (MONO_HANDLE_IS_NULL (o)) {
err = ERR_INVALID_OBJECT;
MonoError error;
GPtrArray *array;
- mono_error_init (&error);
+ error_init (&error);
array = mono_class_get_methods_by_name (klass, name, flags & ~BINDING_FLAGS_IGNORE_CASE, (flags & BINDING_FLAGS_IGNORE_CASE) != 0, TRUE, &error);
if (!is_ok (&error)) {
mono_error_cleanup (&error);
debugger_thread_id = mono_native_thread_id_get ();
- MonoThread *thread = mono_thread_attach (mono_get_root_domain ());
- mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Debugger agent"), TRUE, &error);
+ MonoInternalThread *internal = mono_thread_internal_current ();
+ MonoString *str = mono_string_new_checked (mono_domain_get (), "Debugger agent", &error);
+ mono_error_assert_ok (&error);
+ mono_thread_set_name_internal (internal, str, TRUE, FALSE, &error);
mono_error_assert_ok (&error);
- thread->internal_thread->state |= ThreadState_Background;
- thread->internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
+ internal->state |= ThreadState_Background;
+ internal->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
if (agent_config.defer) {
if (!wait_for_attach ()) {