X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmono-debug.c;h=82722ca453fc55f6f67e0cd32d56cb070b10cbdf;hb=1f771d12ba9c7e4e50810b02d7cf1b466e7009d7;hp=a9d9273b2e5cf09ad432327e8ec4571b0889a0c0;hpb=25f448b44ac14449a3e721f89251027085a2ecb8;p=mono.git diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c index a9d9273b2e5..82722ca453f 100644 --- a/mono/metadata/mono-debug.c +++ b/mono/metadata/mono-debug.c @@ -1,3 +1,13 @@ +/* + * mono-debug.c: + * + * Author: + * Mono Project (http://www.mono-project.com) + * + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + */ + #include #include #include @@ -36,7 +46,8 @@ typedef enum { MONO_DEBUG_DATA_ITEM_UNKNOWN = 0, MONO_DEBUG_DATA_ITEM_CLASS, - MONO_DEBUG_DATA_ITEM_METHOD + MONO_DEBUG_DATA_ITEM_METHOD, + MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE } MonoDebugDataItemType; typedef struct _MonoDebugDataChunk MonoDebugDataChunk; @@ -83,11 +94,21 @@ struct _MonoDebugMethodAddress { guint8 data [MONO_ZERO_LEN_ARRAY]; }; +struct _MonoDebugClassEntry { + guint32 size; + guint8 data [MONO_ZERO_LEN_ARRAY]; +}; + +typedef struct { + gpointer code; + guint32 size; +} MonoDebugDelegateTrampolineEntry; + MonoSymbolTable *mono_symbol_table = NULL; MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE; -gint32 mono_debug_debugger_version = 2; +gint32 mono_debug_debugger_version = 5; +gint32 _mono_debug_using_mono_debugger = 0; -static gboolean in_the_mono_debugger = FALSE; static gboolean mono_debug_initialized = FALSE; GHashTable *mono_debug_handles = NULL; @@ -99,13 +120,12 @@ static MonoDebugHandle *mono_debug_open_image (MonoImage *image, const static MonoDebugHandle *_mono_debug_get_image (MonoImage *image); static void mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data); -static void mono_debug_start_add_type (MonoClass *klass); static void mono_debug_add_type (MonoClass *klass); void _mono_debug_init_corlib (MonoDomain *domain); extern void (*mono_debugger_class_init_func) (MonoClass *klass); -extern void (*mono_debugger_start_class_init_func) (MonoClass *klass); +extern void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass); static MonoDebugDataTable * create_data_table (MonoDomain *domain) @@ -124,8 +144,10 @@ create_data_table (MonoDomain *domain) table->first_chunk = table->current_chunk = chunk; - mono_debug_list_add (&mono_symbol_table->data_tables, table); - g_hash_table_insert (data_table_hash, domain, table); + if (domain) { + mono_debug_list_add (&mono_symbol_table->data_tables, table); + g_hash_table_insert (data_table_hash, domain, table); + } return table; } @@ -183,6 +205,7 @@ free_debug_handle (MonoDebugHandle *handle) if (handle->symfile) mono_debug_close_mono_symbol_file (handle->symfile); /* decrease the refcount added with mono_image_addref () */ + free_data_table (handle->type_table); mono_image_close (handle->image); g_free (handle->image_file); g_free (handle); @@ -200,17 +223,19 @@ mono_debug_init (MonoDebugFormat format) { g_assert (!mono_debug_initialized); + if (_mono_debug_using_mono_debugger) + format = MONO_DEBUG_FORMAT_DEBUGGER; + mono_debug_initialized = TRUE; mono_debug_format = format; - in_the_mono_debugger = format == MONO_DEBUG_FORMAT_DEBUGGER; - mono_debugger_initialize (in_the_mono_debugger); + mono_debugger_initialize (_mono_debug_using_mono_debugger); mono_debugger_lock (); mono_symbol_table = g_new0 (MonoSymbolTable, 1); mono_symbol_table->magic = MONO_DEBUGGER_MAGIC; - mono_symbol_table->version = MONO_DEBUGGER_VERSION; + mono_symbol_table->version = MONO_DEBUGGER_MAJOR_VERSION; mono_symbol_table->total_size = sizeof (MonoSymbolTable); mono_debug_handles = g_hash_table_new_full @@ -219,12 +244,12 @@ mono_debug_init (MonoDebugFormat format) data_table_hash = g_hash_table_new_full ( NULL, NULL, NULL, (GDestroyNotify) free_data_table); - mono_symbol_table->type_table = create_data_table (NULL); - - mono_debugger_start_class_init_func = mono_debug_start_add_type; mono_debugger_class_init_func = mono_debug_add_type; + mono_debugger_class_loaded_methods_func = mono_debugger_class_initialized; mono_install_assembly_load_hook (mono_debug_add_assembly, NULL); + mono_symbol_table->global_data_table = create_data_table (NULL); + mono_debugger_unlock (); } @@ -252,7 +277,7 @@ mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, gboolean mono_debug_using_mono_debugger (void) { - return in_the_mono_debugger; + return _mono_debug_using_mono_debugger; } void @@ -315,6 +340,9 @@ mono_debug_domain_unload (MonoDomain *domain) mono_debugger_unlock (); } +/* + * LOCKING: Assumes the debug lock is held. + */ static MonoDebugHandle * _mono_debug_get_image (MonoImage *image) { @@ -329,11 +357,13 @@ mono_debug_close_image (MonoImage *image) if (!mono_debug_initialized) return; + mono_debugger_lock (); + handle = _mono_debug_get_image (image); - if (!handle) + if (!handle) { + mono_debugger_unlock (); return; - - mono_debugger_lock (); + } mono_debugger_event (MONO_DEBUGGER_EVENT_UNLOAD_MODULE, (guint64) (gsize) handle, handle->index); @@ -352,11 +382,13 @@ mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size) if (mono_image_is_dynamic (image)) return NULL; + mono_debugger_lock (); + handle = _mono_debug_get_image (image); - if (handle != NULL) + if (handle != NULL) { + mono_debugger_unlock (); return handle; - - mono_debugger_lock (); + } handle = g_new0 (MonoDebugHandle, 1); handle->index = ++next_symbol_file_id; @@ -365,7 +397,10 @@ mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size) mono_image_addref (image); handle->image_file = g_strdup (mono_image_get_filename (image)); - handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, in_the_mono_debugger); + handle->type_table = create_data_table (NULL); + + handle->symfile = mono_debug_open_mono_symbols ( + handle, raw_contents, size, _mono_debug_using_mono_debugger); mono_debug_list_add (&mono_symbol_table->symbol_files, handle); @@ -526,7 +561,7 @@ write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr) write_leb128 (var->size, ptr, &ptr); write_leb128 (var->begin_scope, ptr, &ptr); write_leb128 (var->end_scope, ptr, &ptr); - WRITE_UNALIGNED (gpointer, ptr, var->klass); + WRITE_UNALIGNED (gpointer, ptr, var->type); ptr += sizeof (gpointer); *rptr = ptr; } @@ -543,7 +578,6 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma guint8 buffer [BUFSIZ]; guint8 *ptr, *oldptr; guint32 i, size, total_size, max_size; - gint32 last_il_offset = 0, last_native_offset = 0; gboolean is_wrapper = FALSE; mono_debugger_lock (); @@ -561,10 +595,8 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma is_wrapper = TRUE; } - jit->num_lexical_blocks = minfo ? minfo->num_lexical_blocks : 0; - - max_size = 24 + 8 * jit->num_line_numbers + 16 * jit->num_lexical_blocks + - (20 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals); + max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) + + (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals); if (max_size > BUFSIZ) ptr = oldptr = g_malloc (max_size); @@ -578,41 +610,8 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma for (i = 0; i < jit->num_line_numbers; i++) { MonoDebugLineNumberEntry *lne = &jit->line_numbers [i]; - write_sleb128 (lne->il_offset - last_il_offset, ptr, &ptr); - write_sleb128 (lne->native_offset - last_native_offset, ptr, &ptr); - - last_il_offset = lne->il_offset; - last_native_offset = lne->native_offset; - } - - jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks); - for (i = 0; i < jit->num_lexical_blocks; i ++) { - MonoDebugLexicalBlockEntry *jit_lbe = &jit->lexical_blocks [i]; - MonoSymbolFileLexicalBlockEntry *minfo_lbe = &minfo->lexical_blocks [i]; - jit_lbe->il_start_offset = read32 (&(minfo_lbe->_start_offset)); - jit_lbe->native_start_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_start_offset); - - jit_lbe->il_end_offset = read32 (&(minfo_lbe->_end_offset)); - jit_lbe->native_end_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_end_offset); - } - - last_il_offset = 0; - last_native_offset = 0; - write_leb128 (jit->num_lexical_blocks, ptr, &ptr); - for (i = 0; i < jit->num_lexical_blocks; i++) { - MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i]; - - write_sleb128 (lbe->il_start_offset - last_il_offset, ptr, &ptr); - write_sleb128 (lbe->native_start_offset - last_native_offset, ptr, &ptr); - - last_il_offset = lbe->il_start_offset; - last_native_offset = lbe->native_start_offset; - - write_sleb128 (lbe->il_end_offset - last_il_offset, ptr, &ptr); - write_sleb128 (lbe->native_end_offset - last_native_offset, ptr, &ptr); - - last_il_offset = lbe->il_end_offset; - last_native_offset = lbe->native_end_offset; + write_sleb128 (lne->il_offset, ptr, &ptr); + write_sleb128 (lne->native_offset, ptr, &ptr); } *ptr++ = jit->this_var ? 1 : 0; @@ -683,6 +682,27 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma return address; } +void +mono_debug_add_delegate_trampoline (gpointer code, int size) +{ + MonoDebugDelegateTrampolineEntry *entry; + + if (!mono_debug_initialized) + return; + + mono_debugger_lock (); + + entry = (MonoDebugDelegateTrampolineEntry *) allocate_data_item ( + mono_symbol_table->global_data_table, MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE, + sizeof (MonoDebugDelegateTrampolineEntry)); + entry->code = code; + entry->size = size; + + write_data_item (mono_symbol_table->global_data_table, (guint8 *) entry); + + mono_debugger_unlock (); +} + static inline guint32 read_leb128 (guint8 *ptr, guint8 **rptr) { @@ -733,16 +753,28 @@ read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr) var->size = read_leb128 (ptr, &ptr); var->begin_scope = read_leb128 (ptr, &ptr); var->end_scope = read_leb128 (ptr, &ptr); - READ_UNALIGNED (gpointer, ptr, var->klass); + READ_UNALIGNED (gpointer, ptr, var->type); ptr += sizeof (gpointer); *rptr = ptr; } +void +mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit) +{ + if (!jit) + return; + g_free (jit->line_numbers); + g_free (jit->this_var); + g_free (jit->params); + g_free (jit->locals); + g_free (jit); +} + static MonoDebugMethodJitInfo * mono_debug_read_method (MonoDebugMethodAddress *address) { MonoDebugMethodJitInfo *jit; - guint32 i, il_offset = 0, native_offset = 0; + guint32 i; guint8 *ptr; jit = g_new0 (MonoDebugMethodJitInfo, 1); @@ -760,31 +792,8 @@ mono_debug_read_method (MonoDebugMethodAddress *address) for (i = 0; i < jit->num_line_numbers; i++) { MonoDebugLineNumberEntry *lne = &jit->line_numbers [i]; - il_offset += read_sleb128 (ptr, &ptr); - native_offset += read_sleb128 (ptr, &ptr); - - lne->il_offset = il_offset; - lne->native_offset = native_offset; - } - - il_offset = 0; - native_offset = 0; - jit->num_lexical_blocks = read_leb128 (ptr, &ptr); - jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks); - for (i = 0; i < jit->num_lexical_blocks; i ++) { - MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i]; - - il_offset += read_sleb128 (ptr, &ptr); - native_offset += read_sleb128 (ptr, &ptr); - - lbe->il_start_offset = il_offset; - lbe->native_start_offset = native_offset; - - il_offset += read_sleb128 (ptr, &ptr); - native_offset += read_sleb128 (ptr, &ptr); - - lbe->il_end_offset = il_offset; - lbe->native_end_offset = native_offset; + lne->il_offset = read_sleb128 (ptr, &ptr); + lne->native_offset = read_sleb128 (ptr, &ptr); } if (*ptr++) { @@ -805,20 +814,6 @@ mono_debug_read_method (MonoDebugMethodAddress *address) return jit; } -/* - * This is called via the `mono_debugger_class_init_func' from mono_class_init() each time - * a new class is initialized. - */ -static void -mono_debug_start_add_type (MonoClass *klass) -{ - MonoDebugHandle *handle; - - handle = _mono_debug_get_image (klass->image); - if (!handle) - return; -} - static void mono_debug_add_type (MonoClass *klass) { @@ -829,16 +824,18 @@ mono_debug_add_type (MonoClass *klass) guint32 size, total_size, max_size; int base_offset = 0; - handle = _mono_debug_get_image (klass->image); - if (!handle) - return; - if (klass->generic_class || klass->rank || (klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR)) return; mono_debugger_lock (); + handle = _mono_debug_get_image (klass->image); + if (!handle) { + mono_debugger_unlock (); + return; + } + max_size = 12 + sizeof (gpointer); if (max_size > BUFSIZ) ptr = oldptr = g_malloc (max_size); @@ -860,14 +857,13 @@ mono_debug_add_type (MonoClass *klass) g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE); entry = (MonoDebugClassEntry *) allocate_data_item ( - mono_symbol_table->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size); + handle->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size); entry->size = total_size; - entry->symfile_id = handle->index; memcpy (&entry->data, oldptr, size); - write_data_item (mono_symbol_table->type_table, (guint8 *) entry); + write_data_item (handle->type_table, (guint8 *) entry); if (max_size > BUFSIZ) g_free (oldptr); @@ -894,6 +890,10 @@ MonoDebugMethodJitInfo * mono_debug_find_method (MonoMethod *method, MonoDomain *domain) { MonoDebugMethodJitInfo *res; + + if (mono_debug_format == MONO_DEBUG_FORMAT_NONE) + return NULL; + mono_debugger_lock (); res = find_method (method, domain); mono_debugger_unlock (); @@ -929,7 +929,7 @@ mono_debug_lookup_method_addresses (MonoMethod *method) GSList *list; guint8 *ptr; - g_assert (mono_debug_debugger_version == 2); + g_assert ((mono_debug_debugger_version == 4) || (mono_debug_debugger_version == 5)); mono_debugger_lock (); @@ -975,15 +975,19 @@ il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_o jit = find_method (method, domain); if (!jit || !jit->line_numbers) - return -1; + goto cleanup_and_fail; for (i = jit->num_line_numbers - 1; i >= 0; i--) { MonoDebugLineNumberEntry lne = jit->line_numbers [i]; - if (lne.native_offset <= native_offset) + if (lne.native_offset <= native_offset) { + mono_debug_free_method_jit_info (jit); return lne.il_offset; + } } +cleanup_and_fail: + mono_debug_free_method_jit_info (jit); return -1; } @@ -1026,6 +1030,40 @@ mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDoma return location; } +/* + * mono_debug_lookup_locals: + * + * Return information about the local variables of MINFO. + * NAMES and INDEXES are set to g_malloc-ed arrays containing the local names and + * their IL indexes. + * Returns: the number of elements placed into the arrays, or -1 if there is no + * local variable info. + */ +int +mono_debug_lookup_locals (MonoMethod *method, char ***names, int **indexes) +{ + MonoDebugMethodInfo *minfo; + int res; + + *names = NULL; + *indexes = NULL; + + if (mono_debug_format == MONO_DEBUG_FORMAT_NONE) + return -1; + + mono_debugger_lock (); + minfo = _mono_debug_lookup_method (method); + if (!minfo || !minfo->handle || !minfo->handle->symfile || !minfo->handle->symfile->offset_table) { + mono_debugger_unlock (); + return -1; + } + + res = mono_debug_symfile_lookup_locals (minfo, names, indexes); + mono_debugger_unlock (); + + return res; +} + /** * mono_debug_free_source_location: * @location: A `MonoDebugSourceLocation'. @@ -1053,6 +1091,7 @@ mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDom { MonoDebugSourceLocation *location; gchar *fname, *ptr, *res; + int offset; fname = mono_method_full_name (method, TRUE); for (ptr = fname; *ptr; ptr++) { @@ -1062,7 +1101,18 @@ mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDom location = mono_debug_lookup_source_location (method, native_offset, domain); if (!location) { - res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset); + if (mono_debug_initialized) { + mono_debugger_lock (); + offset = il_offset_from_address (method, domain, native_offset); + mono_debugger_unlock (); + } else { + offset = -1; + } + + if (offset < 0) + res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset); + else + res = g_strdup_printf ("at %s ", fname, offset, native_offset); g_free (fname); return res; }