+#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <mono/metadata/class.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/tokentype.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/debug-mono-symfile.h>
-#include <mono/jit/codegen.h>
-#include <mono/jit/debug.h>
#include "debug-private.h"
-#include "helpers.h"
+
+/*
+ * NOTE: Functions and variables starting with `mono_debug_' and `debug_' are
+ * part of the general debugging code.
+ *
+ * Functions and variables starting with `mono_debugger_' and `debugger_'
+ * are only used when the JIT is running inside the Mono Debugger.
+ *
+ * FIXME: This file needs some API loving.
+ */
/* This is incremented each time the symbol table is modified.
* The debugger looks at this variable and if it has a higher value than its current
- * copy of the symbol table, it must call debugger_update_symbol_file_table().
+ * copy of the symbol table, it must call mono_debug_update_symbol_file_table().
*/
-static guint32 debugger_symbol_file_table_generation = 0;
-static guint32 debugger_symbol_file_table_modified = 0;
+guint32 mono_debugger_symbol_file_table_generation = 0;
+guint32 mono_debugger_symbol_file_table_modified = 0;
/* Caution: This variable may be accessed at any time from the debugger;
* it is very important not to modify the memory it is pointing to
* without previously setting this pointer back to NULL.
*/
-static MonoDebuggerSymbolFileTable *debugger_symbol_file_table = NULL;
+MonoDebuggerSymbolFileTable *mono_debugger_symbol_file_table = NULL;
/* Caution: This function MUST be called before touching the symbol table! */
static void release_symbol_file_table (void);
-static void initialize_debugger_support (void);
+MonoDebugHandle *mono_debug_handle = NULL;
+gboolean mono_debug_initialized = FALSE;
-static MonoDebugHandle *mono_debug_handle = NULL;
-static void (*debugger_notification_code) (void) = NULL;
-static pthread_cond_t debugger_thread_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t debugger_thread_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static CRITICAL_SECTION debugger_lock_mutex;
-static guint64 debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument);
-static guint64 debugger_remove_breakpoint (guint64 breakpoint);
-static int debugger_update_symbol_file_table (void);
+extern void (*mono_debugger_class_init_func) (MonoClass *klass);
static void mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data);
static void mono_debug_close_assembly (AssemblyDebugInfo* info);
static AssemblyDebugInfo *mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image);
-/*
- * This is a global data symbol which is read by the debugger.
- */
-MonoDebuggerInfo MONO_DEBUGGER__debugger_info = {
- MONO_SYMBOL_FILE_DYNAMIC_MAGIC,
- MONO_SYMBOL_FILE_DYNAMIC_VERSION,
- sizeof (MonoDebuggerInfo),
- &mono_generic_trampoline_code,
- &mono_breakpoint_trampoline_code,
- &debugger_symbol_file_table_generation,
- &debugger_symbol_file_table_modified,
- &debugger_notification_code,
- &debugger_symbol_file_table,
- &debugger_update_symbol_file_table,
- &mono_compile_method,
- &debugger_insert_breakpoint,
- &debugger_remove_breakpoint,
- &mono_runtime_invoke
+static int running_in_the_mono_debugger = FALSE;
+void (*mono_debugger_event_handler) (MonoDebuggerEvent event, gpointer data, gpointer data2) = NULL;
+
+#ifndef PLATFORM_WIN32
+
+MonoDebuggerIOLayer mono_debugger_io_layer = {
+ InitializeCriticalSection, DeleteCriticalSection, TryEnterCriticalSection,
+ EnterCriticalSection, LeaveCriticalSection, WaitForSingleObject, SignalObjectAndWait,
+ WaitForMultipleObjects, CreateSemaphore, ReleaseSemaphore, CreateThread
};
-static void
-mono_debugger_lock (void)
+#endif
+
+void
+mono_debugger_event (MonoDebuggerEvent event, gpointer data, gpointer data2)
{
- pthread_mutex_lock (&debugger_thread_mutex);
+ if (mono_debugger_event_handler)
+ (* mono_debugger_event_handler) (event, data, data2);
}
-static void
-mono_debugger_unlock (void)
+void
+mono_debug_init (int in_the_debugger)
+{
+ if (mono_debug_initialized)
+ return;
+
+ InitializeCriticalSection (&debugger_lock_mutex);
+ mono_debug_initialized = TRUE;
+ running_in_the_mono_debugger = in_the_debugger;
+}
+
+gpointer
+mono_debug_create_notification_function (gpointer *notification_address)
+{
+ guint8 *ptr, *buf;
+
+ ptr = buf = g_malloc0 (16);
+ mono_debug_codegen_breakpoint (&buf);
+ if (notification_address)
+ *notification_address = buf;
+ mono_debug_codegen_ret (&buf);
+
+ return ptr;
+}
+
+void
+mono_debug_lock (void)
{
- pthread_mutex_unlock (&debugger_thread_mutex);
+ if (mono_debug_initialized)
+ EnterCriticalSection (&debugger_lock_mutex);
+}
+
+void
+mono_debug_unlock (void)
+{
+ if (mono_debug_initialized)
+ LeaveCriticalSection (&debugger_lock_mutex);
}
static void
}
static void
-debug_arg_warning (const char *message)
+free_wrapper_info (DebugWrapperInfo *winfo)
{
- g_warning ("Error while processing --debug-args arguments: %s", message);
+ g_free (winfo);
}
-static gchar *
-replace_suffix (const char *filename, const char *new_suffix)
+static void
+debug_arg_warning (const char *message)
{
- const char *pos = strrchr (filename, '.');
-
- if (!pos)
- return g_strdup_printf ("%s.%s", filename, new_suffix);
- else {
- int len = pos - filename;
- gchar *retval = g_malloc0 (len + strlen (new_suffix) + 2);
- memcpy (retval, filename, len);
- retval [len] = '.';
- memcpy (retval + len + 1, new_suffix, strlen (new_suffix) + 1);
- return retval;
- }
+ g_warning ("Error while processing --debug-args arguments: %s", message);
}
MonoDebugHandle*
g_assert (!mono_debug_handle);
- mono_debugger_lock ();
- release_symbol_file_table ();
-
debug = g_new0 (MonoDebugHandle, 1);
debug->name = g_strdup (assembly->image->name);
debug->format = format;
+ debug->source_files = g_ptr_array_new ();
debug->producer_name = g_strdup_printf ("Mono JIT compiler version %s", VERSION);
debug->next_idx = 100;
debug->dirty = TRUE;
debug->type_hash = g_hash_table_new (NULL, NULL);
- debug->source_files = g_ptr_array_new ();
debug->images = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) mono_debug_close_assembly);
debug->flags |= MONO_DEBUG_FLAGS_DONT_CREATE_IL_FILES;
continue;
}
- } else {
- if (!strcmp (arg, "internal_mono_debugger")) {
- debug->flags |= MONO_DEBUG_FLAGS_MONO_DEBUGGER;
- initialize_debugger_support ();
- continue;
- }
}
message = g_strdup_printf ("Unknown argument `%s'.", arg);
debug->objfile = g_strdup_printf ("%s.o", g_basename (debug->name));
break;
case MONO_DEBUG_FORMAT_MONO:
+ mono_debugger_class_init_func = mono_debug_add_type;
break;
default:
g_assert_not_reached ();
}
+ mono_debug_lock ();
+ release_symbol_file_table ();
+
mono_debug_handle = debug;
mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
mono_debug_add_type (mono_defaults.serializationinfo_class);
mono_debug_add_type (mono_defaults.streamingcontext_class);
- mono_debugger_unlock ();
+ mono_debug_update_symbol_file_table ();
+
+ mono_debug_unlock ();
return debug;
}
if (!mono_debug_handle)
return;
- mono_debugger_lock ();
+ mono_debug_lock ();
mono_debug_open_image (mono_debug_handle, assembly->image);
- mono_debugger_unlock ();
+ mono_debug_unlock ();
}
static void
}
}
-static void
-record_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, guint32 line)
-{
- MonoDebugLineNumberEntry *lne = g_new0 (MonoDebugLineNumberEntry, 1);
-
- lne->address = address;
- lne->offset = offset;
- lne->line = line;
-
- g_array_append_val (minfo->jit->line_numbers, *lne);
-}
-
-static void
-debug_generate_method_lines (AssemblyDebugInfo *info, MonoDebugMethodInfo *minfo, MonoFlowGraph* cfg)
-{
- guint32 st_address, st_line;
- DebugMethodInfo *priv = minfo->user_data;
- int i;
-
- if (!priv || !info->moffsets)
- return;
-
- minfo->jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
-
- st_line = priv->first_line;
- st_address = minfo->jit->prologue_end;
-
- /* This is the first actual code line of the method. */
- record_line_number (minfo, st_address, 0, st_line);
-
- /* start lines of basic blocks */
- for (i = 0; i < cfg->block_count; ++i) {
- int j;
-
- for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
- MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
- gint32 line_inc = 0, addr_inc;
-
- if (!i && !j) {
- st_line = priv->first_line;
- st_address = t->addr;
- }
-
- addr_inc = t->addr - st_address;
- st_address += addr_inc;
-
- if (t->cli_addr != -1) {
- int *lines = info->moffsets + st_line;
- int *k = lines;
-
- while ((*k != -1) && (*k < t->cli_addr))
- k++;
-
- line_inc = k - lines;
- }
-
- st_line += line_inc;
-
- if (t->cli_addr != -1)
- record_line_number (minfo, st_address, t->cli_addr, st_line);
- }
- }
-}
-
-static void
-generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, int debug)
+void
+_mono_debug_generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, int debug)
{
int i;
}
}
-static void
-debug_update_il_offsets (AssemblyDebugInfo *info, MonoDebugMethodInfo *minfo, MonoFlowGraph* cfg)
-{
- MonoMethodHeader *header;
- guint32 address, offset;
- int debug = 0;
- int i;
-
- g_assert (info->symfile);
- if (info->symfile->is_dynamic)
- return;
-
- g_assert (!minfo->jit->line_numbers);
- minfo->jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
-
- address = minfo->jit->prologue_end;
- offset = 0;
-
- g_assert (((MonoMethodNormal*)minfo->method)->header);
- header = ((MonoMethodNormal*)minfo->method)->header;
-
-#if 0
- if (!strcmp (minfo->method->name, "Test") || !strcmp (minfo->method->name, "Main")) {
- MonoMethodHeader *header = ((MonoMethodNormal*)minfo->method)->header;
-
- debug = 1;
- mono_disassemble_code (minfo->jit->code_start, minfo->jit->code_size,
- minfo->method->name);
-
- printf ("\nDisassembly:\n%s\n", mono_disasm_code (
- NULL, minfo->method, header->code, header->code + header->code_size));
- g_message (G_STRLOC ": %x - %x", minfo->jit->prologue_end, minfo->jit->epilogue_begin);
- }
-#endif
-
- generate_line_number (minfo, address, offset, debug);
-
- /* start lines of basic blocks */
- for (i = 0; i < cfg->block_count; ++i) {
- int j;
-
- for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
- MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
-
- if ((t->cli_addr == -1) || (t->cli_addr == offset) || (t->addr == address))
- continue;
-
- offset = t->cli_addr;
- address = t->addr;
-
- generate_line_number (minfo, address, offset, debug);
- }
- }
-
- generate_line_number (minfo, minfo->jit->epilogue_begin, header->code_size, debug);
-
- if (debug) {
- for (i = 0; i < minfo->jit->line_numbers->len; i++) {
- MonoDebugLineNumberEntry lne = g_array_index (
- minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
-
- g_message (G_STRLOC ": %x,%x,%d", lne.address, lne.offset, lne.line);
- }
- }
-}
-
-static AssemblyDebugInfo *
-mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
+AssemblyDebugInfo *
+_mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
{
return g_hash_table_lookup (debug->images, image);
}
AssemblyDebugInfo *info;
MonoAssembly **ptr;
- info = mono_debug_get_image (debug, image);
+ info = _mono_debug_get_image (debug, image);
if (info != NULL)
return info;
info->handle = debug;
info->methods = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) free_method_info);
-
- info->source_file = debug->source_files->len;
- g_ptr_array_add (debug->source_files, g_strdup_printf ("%s.il", image->assembly_name));
+ info->wrapper_methods = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify) free_wrapper_info);
g_hash_table_insert (debug->images, image, info);
for (ptr = image->references; ptr && *ptr; ptr++)
mono_debug_add_assembly (*ptr, NULL);
+ if (image->assembly->dynamic)
+ return info;
+
switch (info->format) {
case MONO_DEBUG_FORMAT_STABS:
case MONO_DEBUG_FORMAT_DWARF2:
g_free (dirname);
} else
info->ilfile = g_strdup_printf ("%s.il", info->name);
+ info->source_file = debug->source_files->len;
+ g_ptr_array_add (debug->source_files, info->ilfile);
break;
case MONO_DEBUG_FORMAT_MONO:
- info->filename = replace_suffix (image->name, "dbg");
- if (g_file_test (info->filename, G_FILE_TEST_EXISTS))
- info->symfile = mono_debug_open_mono_symbol_file (info->image, info->filename, TRUE);
- else if (debug->flags & MONO_DEBUG_FLAGS_MONO_DEBUGGER)
- info->symfile = mono_debug_create_mono_symbol_file (info->image);
- debugger_symbol_file_table_generation++;
+ info->symfile = mono_debug_open_mono_symbol_file (info->image, running_in_the_mono_debugger);
+ mono_debugger_symbol_file_table_generation++;
break;
default:
void
mono_debug_make_symbols (void)
{
- release_symbol_file_table ();
-
if (!mono_debug_handle || !mono_debug_handle->dirty)
return;
mono_debug_write_dwarf2 (mono_debug_handle);
break;
case MONO_DEBUG_FORMAT_MONO:
- debugger_update_symbol_file_table ();
+ mono_debug_update_symbol_file_table ();
break;
default:
g_assert_not_reached ();
break;
}
g_hash_table_destroy (info->methods);
+ g_hash_table_destroy (info->wrapper_methods);
g_free (info->mlines);
g_free (info->moffsets);
g_free (info->name);
mono_debug_write_symbols (mono_debug_handle);
g_hash_table_destroy (mono_debug_handle->images);
- g_ptr_array_free (mono_debug_handle->source_files, TRUE);
+ g_ptr_array_free (mono_debug_handle->source_files, FALSE);
g_hash_table_destroy (mono_debug_handle->type_hash);
g_free (mono_debug_handle->producer_name);
g_free (mono_debug_handle->name);
return -1;
}
-static gint32
-address_from_il_offset (MonoDebugMethodInfo *minfo, guint32 il_offset)
-{
- int i;
-
- if (!minfo->jit || !minfo->jit->line_numbers)
- return -1;
-
- for (i = minfo->jit->line_numbers->len - 1; i >= 0; i--) {
- MonoDebugLineNumberEntry lne = g_array_index (
- minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
-
- if (lne.offset <= il_offset)
- return lne.address;
- }
-
- return -1;
-}
-
void
mono_debug_add_type (MonoClass *klass)
{
if (!mono_debug_handle)
return;
- info = mono_debug_get_image (mono_debug_handle, klass->image);
+ info = _mono_debug_get_image (mono_debug_handle, klass->image);
g_assert (info);
if (mono_debug_handle->format != MONO_DEBUG_FORMAT_MONO)
return;
if (info->symfile) {
- mono_debugger_lock ();
+ mono_debug_lock ();
mono_debug_symfile_add_type (info->symfile, klass);
- debugger_symbol_file_table_modified++;
- pthread_cond_signal (&debugger_thread_cond);
- mono_debugger_unlock ();
+ mono_debugger_event (MONO_DEBUGGER_EVENT_TYPE_ADDED, info->symfile, klass);
+ mono_debug_unlock ();
}
}
-static gint32
-il_offset_from_position (MonoFlowGraph *cfg, MonoPosition *pos)
-{
- MonoBBlock *bblock;
- MBTree *tree;
-
- if (pos->abs_pos == 0)
- return -1;
-
- if (pos->pos.bid >= cfg->block_count)
- return -1;
-
- bblock = &cfg->bblocks [pos->pos.bid];
- if (pos->pos.tid >= bblock->forest->len)
- return -1;
-
- tree = (MBTree *) g_ptr_array_index (bblock->forest, pos->pos.tid);
-
- return tree->cli_addr;
-}
-
struct LookupMethodData
{
MonoDebugMethodInfo *minfo;
data->minfo = g_hash_table_lookup (info->methods, data->method);
}
-static MonoDebugMethodInfo *
-lookup_method (MonoMethod *method)
+MonoDebugMethodInfo *
+_mono_debug_lookup_method (MonoMethod *method)
{
struct LookupMethodData data = { NULL, method };
}
void
-mono_debug_add_method (MonoFlowGraph *cfg)
+mono_debug_add_wrapper (MonoMethod *method, MonoMethod *wrapper_method)
{
- MonoMethod *method = cfg->method;
MonoClass *klass = method->klass;
AssemblyDebugInfo* info;
- MonoDebugMethodJitInfo *jit;
MonoDebugMethodInfo *minfo;
- int i;
+ DebugWrapperInfo *winfo;
+ MonoDebugMethodJitInfo *jit;
if (!mono_debug_handle)
return;
- mono_class_init (klass);
-
- if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
- (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
- (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
- (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
+ if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
return;
- if (method->wrapper_type != MONO_WRAPPER_NONE)
- return;
+ mono_class_init (klass);
- info = mono_debug_get_image (mono_debug_handle, klass->image);
+ info = _mono_debug_get_image (mono_debug_handle, klass->image);
g_assert (info);
- minfo = lookup_method (method);
+ minfo = _mono_debug_lookup_method (method);
if (!minfo || minfo->jit)
return;
- mono_debugger_lock ();
+ winfo = g_hash_table_lookup (info->wrapper_methods, wrapper_method);
+ g_assert (winfo);
+
+ mono_debug_lock ();
mono_debug_handle->dirty = TRUE;
minfo->jit = jit = g_new0 (MonoDebugMethodJitInfo, 1);
- jit->code_start = cfg->start;
- jit->code_size = cfg->epilogue_end;
- jit->prologue_end = cfg->prologue_end;
- jit->epilogue_begin = cfg->epilog;
- jit->num_params = method->signature->param_count;
- jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
-
- if (method->signature->hasthis) {
- MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index;
-
- jit->this_var = g_new0 (MonoDebugVarInfo, 1);
- jit->this_var->offset = ptr->offset;
- jit->this_var->size = ptr->size;
- }
-
- for (i = 0; i < jit->num_params; i++) {
- MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index +
- method->signature->hasthis;
-
- jit->params [i].offset = ptr [i].offset;
- jit->params [i].size = ptr [i].size;
- }
-
- debug_generate_method_lines (info, minfo, cfg);
- if (info->format == MONO_DEBUG_FORMAT_MONO)
- debug_update_il_offsets (info, minfo, cfg);
-
- if (!method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
- MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
- MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->locals_start_index;
- MonoDebugVarInfo *locals;
-
- locals = g_new0 (MonoDebugVarInfo, header->num_locals);
- for (i = 0; i < header->num_locals; i++) {
- gint32 begin_offset, end_offset;
- gint32 begin_scope, end_scope;
-
- if (ptr [i].reg >= 0) {
- locals [i].index = ptr [i].reg | MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER;
- locals [i].offset = 0;
- } else
- locals [i].offset = ptr [i].offset;
-
- locals [i].size = ptr [i].size;
-
- begin_offset = il_offset_from_position (cfg, &ptr [i].range.first_use);
- end_offset = il_offset_from_position (cfg, &ptr [i].range.last_use);
- if (end_offset >= 0)
- end_offset++;
-
- if (begin_offset >= 0)
- begin_scope = address_from_il_offset (minfo, begin_offset);
- else
- begin_scope = -1;
- if (end_offset >= 0)
- end_scope = address_from_il_offset (minfo, end_offset);
- else
- end_scope = -1;
-
- if (begin_scope > 0)
- locals [i].begin_scope = begin_scope;
- else
- locals [i].begin_scope = jit->prologue_end;
- if (end_scope > 0)
- locals [i].end_scope = end_scope;
- else
- locals [i].end_scope = jit->epilogue_begin;
- }
-
- jit->num_locals = header->num_locals;
- jit->locals = locals;
- }
+ jit->code_start = winfo->code_start;
+ jit->code_size = winfo->code_size;
+ jit->prologue_end = 0;
+ jit->epilogue_begin = winfo->code_size;
+ jit->num_params = 0;
+ jit->wrapper_addr = method->addr;
if (info->symfile) {
mono_debug_symfile_add_method (info->symfile, method);
- debugger_symbol_file_table_modified++;
- pthread_cond_signal (&debugger_thread_cond);
+ mono_debugger_event (MONO_DEBUGGER_EVENT_METHOD_ADDED, info->symfile, method);
}
- mono_debugger_unlock ();
+ mono_debug_unlock ();
}
gchar *
mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number)
{
- MonoDebugMethodInfo *minfo = lookup_method (method);
+ MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
if (!minfo)
return NULL;
if (address < 0)
return -1;
- minfo = lookup_method (method);
+ minfo = _mono_debug_lookup_method (method);
if (!minfo || !minfo->il_offsets)
return -1;
if (il_offset < 0)
return -1;
- minfo = lookup_method (method);
+ minfo = _mono_debug_lookup_method (method);
if (!minfo || !minfo->il_offsets)
return -1;
- return address_from_il_offset (minfo, il_offset);
+ return _mono_debug_address_from_il_offset (minfo, il_offset);
}
static void
{
MonoDebuggerSymbolFileTable *temp;
- if (!debugger_symbol_file_table)
+ if (!mono_debugger_symbol_file_table)
return;
/*
* before freeing the area.
*/
- temp = debugger_symbol_file_table;
- debugger_symbol_file_table = NULL;
- g_free (debugger_symbol_file_table);
+ temp = mono_debugger_symbol_file_table;
+ mono_debugger_symbol_file_table = NULL;
+ g_free (mono_debugger_symbol_file_table);
}
static void
{
AssemblyDebugInfo *info = (AssemblyDebugInfo *) value;
- if (!info->symfile || (info->format != MONO_DEBUG_FORMAT_MONO))
+ if (!info->symfile)
+ return;
+ if (info->format != MONO_DEBUG_FORMAT_MONO)
return;
++ (* (int *) user_data);
AssemblyDebugInfo *info = (AssemblyDebugInfo *) value;
struct SymfileTableData *data = (struct SymfileTableData *) user_data;
- if (!info->symfile || (info->format != MONO_DEBUG_FORMAT_MONO))
+ if (!info->symfile)
+ return;
+ if (info->format != MONO_DEBUG_FORMAT_MONO)
return;
data->symfile_table->symfiles [data->index++] = info->symfile;
}
-static int
-debugger_update_symbol_file_table (void)
+int
+mono_debug_update_symbol_file_table (void)
{
int count = 0;
MonoDebuggerSymbolFileTable *symfile_table;
if (!mono_debug_handle)
return FALSE;
- mono_debugger_lock ();
+ mono_debug_lock ();
g_hash_table_foreach (mono_debug_handle->images, update_symbol_file_table_count_func, &count);
symfile_table->version = MONO_SYMBOL_FILE_DYNAMIC_VERSION;
symfile_table->total_size = size;
symfile_table->count = count;
- symfile_table->generation = debugger_symbol_file_table_generation;
+ symfile_table->generation = mono_debugger_symbol_file_table_generation;
+ symfile_table->global_symfile = mono_debugger_global_symbol_file;
data.symfile_table = symfile_table;
data.index = 0;
g_hash_table_foreach (mono_debug_handle->images, update_symbol_file_table_func, &data);
- debugger_symbol_file_table = symfile_table;
+ mono_debugger_symbol_file_table = symfile_table;
- mono_debugger_unlock ();
+ mono_debug_unlock ();
return TRUE;
}
-extern void (*mono_debugger_class_init_func) (MonoClass *klass);
-
-static gboolean has_mono_debugger_support = FALSE;
-
-/*
- * NOTE: We must not call any functions here which we ever may want to debug !
- */
-static gpointer
-debugger_thread_func (gpointer unused)
-{
- raise (SIGSTOP);
-
- g_message (G_STRLOC);
- pthread_mutex_lock (&debugger_thread_mutex);
-
- while (TRUE) {
- /* Send notification. */
- debugger_notification_code ();
-
- /* Wait for an event. */
- pthread_cond_wait (&debugger_thread_cond, &debugger_thread_mutex);
- }
-
- return NULL;
-}
-
-static void
-initialize_debugger_support ()
-{
- guint8 *buf;
- pthread_t thread;
- int ret;
-
- if (has_mono_debugger_support)
- return;
- has_mono_debugger_support = TRUE;
-
- mono_debugger_class_init_func = mono_debug_add_type;
-
- debugger_notification_code = g_malloc0 (16);
- buf = (guint8 *) debugger_notification_code;
- x86_breakpoint (buf);
- x86_ret (buf);
-
- ret = pthread_create (&thread, NULL, debugger_thread_func, NULL);
- g_assert (ret == 0);
-}
-
static GPtrArray *breakpoints = NULL;
int
return info->index;
}
-static guint64
-debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument)
-{
- MonoMethodDesc *desc;
-
- desc = mono_method_desc_new (string_argument, FALSE);
- if (!desc)
- return 0;
-
- return mono_insert_breakpoint_full (desc, TRUE);
-}
-
-static guint64
-debugger_remove_breakpoint (guint64 breakpoint)
+int
+mono_remove_breakpoint (int breakpoint_id)
{
int i;
for (i = 0; i < breakpoints->len; i++) {
MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
- if (info->index != breakpoint)
+ if (info->index != breakpoint_id)
continue;
mono_method_desc_free (info->desc);
return 0;
}
-int
-mono_remove_breakpoint (int breakpoint_id)
-{
- return debugger_remove_breakpoint (breakpoint_id);
-}
-
int
mono_insert_breakpoint (const gchar *method_name, gboolean include_namespace)
{
if (!desc)
return 0;
- return mono_insert_breakpoint_full (desc, has_mono_debugger_support);
+ return mono_insert_breakpoint_full (desc, running_in_the_mono_debugger);
}
int
return 0;
}
+
+void
+mono_debugger_trampoline_breakpoint_callback (void)
+{
+ mono_debugger_event (MONO_DEBUGGER_EVENT_BREAKPOINT_TRAMPOLINE, NULL, NULL);
+}