X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmono-debug.c;h=4230399ec10242c2c3d339e80ed8271981bb4f96;hb=HEAD;hp=ba9898781716d25e8d733d985411d86140929e38;hpb=4e4013721304d8da777f3137a9857e387c7cf548;p=mono.git diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c index ba989878171..4230399ec10 100644 --- a/mono/metadata/mono-debug.c +++ b/mono/metadata/mono-debug.c @@ -1,5 +1,5 @@ -/* - * mono-debug.c: +/** + * \file * * Author: * Mono Project (http://www.mono-project.com) @@ -7,6 +7,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -16,11 +17,14 @@ #include #include #include -#include +#include #include #include #include +#include #include +#include +#include #include #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) @@ -100,7 +104,7 @@ lookup_data_table (MonoDomain *domain) { MonoDebugDataTable *table; - table = g_hash_table_lookup (data_table_hash, domain); + table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain); if (!table) { g_error ("lookup_data_table () failed for %p\n", domain); g_assert (table); @@ -174,6 +178,9 @@ mono_debug_cleanup (void) } } +/** + * mono_debug_domain_create: + */ void mono_debug_domain_create (MonoDomain *domain) { @@ -197,7 +204,7 @@ mono_debug_domain_unload (MonoDomain *domain) mono_debugger_lock (); - table = g_hash_table_lookup (data_table_hash, domain); + table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain); if (!table) { g_warning (G_STRLOC ": unloading unknown domain %p / %d", domain, mono_domain_get_id (domain)); @@ -216,9 +223,12 @@ mono_debug_domain_unload (MonoDomain *domain) static MonoDebugHandle * mono_debug_get_image (MonoImage *image) { - return g_hash_table_lookup (mono_debug_handles, image); + return (MonoDebugHandle *)g_hash_table_lookup (mono_debug_handles, image); } +/** + * mono_debug_close_image: + */ void mono_debug_close_image (MonoImage *image) { @@ -327,9 +337,9 @@ mono_debug_lookup_method_internal (MonoMethod *method) /** * mono_debug_lookup_method: * - * Lookup symbol file information for the method @method. The returned - * `MonoDebugMethodInfo' is a private structure, but it can be passed to - * mono_debug_symfile_lookup_location(). + * Lookup symbol file information for the method \p method. The returned + * \c MonoDebugMethodInfo is a private structure, but it can be passed to + * \c mono_debug_symfile_lookup_location. */ MonoDebugMethodInfo * mono_debug_lookup_method (MonoMethod *method) @@ -427,6 +437,9 @@ write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr) *rptr = ptr; } +/** + * mono_debug_add_method: + */ MonoDebugMethodAddress * mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain) { @@ -444,7 +457,7 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals); if (max_size > BUFSIZ) - ptr = oldptr = g_malloc (max_size); + ptr = oldptr = (guint8 *)g_malloc (max_size); else ptr = oldptr = buffer; @@ -458,23 +471,25 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma write_sleb128 (lne->il_offset, ptr, &ptr); write_sleb128 (lne->native_offset, ptr, &ptr); } - - *ptr++ = jit->this_var ? 1 : 0; - if (jit->this_var) - write_variable (jit->this_var, ptr, &ptr); - - write_leb128 (jit->num_params, ptr, &ptr); - for (i = 0; i < jit->num_params; i++) - write_variable (&jit->params [i], ptr, &ptr); - - write_leb128 (jit->num_locals, ptr, &ptr); - for (i = 0; i < jit->num_locals; i++) - write_variable (&jit->locals [i], ptr, &ptr); - - *ptr++ = jit->gsharedvt_info_var ? 1 : 0; - if (jit->gsharedvt_info_var) { - write_variable (jit->gsharedvt_info_var, ptr, &ptr); - write_variable (jit->gsharedvt_locals_var, ptr, &ptr); + write_leb128 (jit->has_var_info, ptr, &ptr); + if (jit->has_var_info) { + *ptr++ = jit->this_var ? 1 : 0; + if (jit->this_var) + write_variable (jit->this_var, ptr, &ptr); + + write_leb128 (jit->num_params, ptr, &ptr); + for (i = 0; i < jit->num_params; i++) + write_variable (&jit->params [i], ptr, &ptr); + + write_leb128 (jit->num_locals, ptr, &ptr); + for (i = 0; i < jit->num_locals; i++) + write_variable (&jit->locals [i], ptr, &ptr); + + *ptr++ = jit->gsharedvt_info_var ? 1 : 0; + if (jit->gsharedvt_info_var) { + write_variable (jit->gsharedvt_info_var, ptr, &ptr); + write_variable (jit->gsharedvt_locals_var, ptr, &ptr); + } } size = ptr - oldptr; @@ -482,9 +497,9 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma total_size = size + sizeof (MonoDebugMethodAddress); if (method_is_dynamic (method)) { - address = g_malloc0 (total_size); + address = (MonoDebugMethodAddress *)g_malloc0 (total_size); } else { - address = mono_mempool_alloc (table->mp, total_size); + address = (MonoDebugMethodAddress *)mono_mempool_alloc (table->mp, total_size); } address->code_start = jit->code_start; @@ -515,7 +530,7 @@ mono_debug_remove_method (MonoMethod *method, MonoDomain *domain) table = lookup_data_table (domain); - address = g_hash_table_lookup (table->method_address_hash, method); + address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method); if (address) g_free (address); @@ -524,6 +539,9 @@ mono_debug_remove_method (MonoMethod *method, MonoDomain *domain) mono_debugger_unlock (); } +/** + * mono_debug_add_delegate_trampoline: + */ void mono_debug_add_delegate_trampoline (gpointer code, int size) { @@ -579,7 +597,7 @@ 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->type); + READ_UNALIGNED (MonoType *, ptr, var->type); ptr += sizeof (gpointer); *rptr = ptr; } @@ -622,27 +640,29 @@ mono_debug_read_method (MonoDebugMethodAddress *address) lne->il_offset = read_sleb128 (ptr, &ptr); lne->native_offset = read_sleb128 (ptr, &ptr); } + jit->has_var_info = read_leb128 (ptr, &ptr); + if (jit->has_var_info) { + if (*ptr++) { + jit->this_var = g_new0 (MonoDebugVarInfo, 1); + read_variable (jit->this_var, ptr, &ptr); + } - if (*ptr++) { - jit->this_var = g_new0 (MonoDebugVarInfo, 1); - read_variable (jit->this_var, ptr, &ptr); - } - - jit->num_params = read_leb128 (ptr, &ptr); - jit->params = g_new0 (MonoDebugVarInfo, jit->num_params); - for (i = 0; i < jit->num_params; i++) - read_variable (&jit->params [i], ptr, &ptr); - - jit->num_locals = read_leb128 (ptr, &ptr); - jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals); - for (i = 0; i < jit->num_locals; i++) - read_variable (&jit->locals [i], ptr, &ptr); - - if (*ptr++) { - jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1); - jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1); - read_variable (jit->gsharedvt_info_var, ptr, &ptr); - read_variable (jit->gsharedvt_locals_var, ptr, &ptr); + jit->num_params = read_leb128 (ptr, &ptr); + jit->params = g_new0 (MonoDebugVarInfo, jit->num_params); + for (i = 0; i < jit->num_params; i++) + read_variable (&jit->params [i], ptr, &ptr); + + jit->num_locals = read_leb128 (ptr, &ptr); + jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals); + for (i = 0; i < jit->num_locals; i++) + read_variable (&jit->locals [i], ptr, &ptr); + + if (*ptr++) { + jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1); + jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1); + read_variable (jit->gsharedvt_info_var, ptr, &ptr); + read_variable (jit->gsharedvt_locals_var, ptr, &ptr); + } } return jit; @@ -655,7 +675,7 @@ find_method (MonoMethod *method, MonoDomain *domain) MonoDebugMethodAddress *address; table = lookup_data_table (domain); - address = g_hash_table_lookup (table->method_address_hash, method); + address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method); if (!address) return NULL; @@ -711,8 +731,8 @@ cleanup_and_fail: /** * mono_debug_il_offset_from_address: * - * Compute the IL offset corresponding to NATIVE_OFFSET inside the native - * code of METHOD in DOMAIN. + * Compute the IL offset corresponding to \p native_offset inside the native + * code of \p method in \p domain. */ gint32 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset) @@ -730,14 +750,12 @@ mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint /** * mono_debug_lookup_source_location: - * @address: Native offset within the @method's machine code. - * + * \param address Native offset within the \p method's machine code. * Lookup the source code corresponding to the machine instruction located at - * native offset @address within @method. - * - * The returned `MonoDebugSourceLocation' contains both file / line number + * native offset \p address within \p method. + * The returned \c MonoDebugSourceLocation contains both file / line number * information and the corresponding IL offset. It must be freed by - * mono_debug_free_source_location(). + * \c mono_debug_free_source_location. */ MonoDebugSourceLocation * mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain) @@ -775,6 +793,40 @@ mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDoma return location; } +/** + * mono_debug_lookup_source_location_by_il: + * + * Same as mono_debug_lookup_source_location but take an IL_OFFSET argument. + */ +MonoDebugSourceLocation * +mono_debug_lookup_source_location_by_il (MonoMethod *method, guint32 il_offset, MonoDomain *domain) +{ + MonoDebugMethodInfo *minfo; + MonoDebugSourceLocation *location; + + if (mono_debug_format == MONO_DEBUG_FORMAT_NONE) + return NULL; + + mono_debugger_lock (); + minfo = mono_debug_lookup_method_internal (method); + if (!minfo || !minfo->handle) { + mono_debugger_unlock (); + return NULL; + } + + if (!minfo->handle->ppdb && (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))) { + mono_debugger_unlock (); + return NULL; + } + + if (minfo->handle->ppdb) + location = mono_ppdb_lookup_location (minfo, il_offset); + else + location = mono_debug_symfile_lookup_location (minfo, il_offset); + mono_debugger_unlock (); + return location; +} + MonoDebugSourceLocation * mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset) { @@ -841,11 +893,56 @@ mono_debug_free_locals (MonoDebugLocalsInfo *info) g_free (info); } +/* +* mono_debug_lookup_method_async_debug_info: +* +* Return information about the async stepping information of method. +* The result should be freed using mono_debug_free_async_debug_info (). +*/ +MonoDebugMethodAsyncInfo* +mono_debug_lookup_method_async_debug_info (MonoMethod *method) +{ + MonoDebugMethodInfo *minfo; + MonoDebugMethodAsyncInfo *res = NULL; + + if (mono_debug_format == MONO_DEBUG_FORMAT_NONE) + return NULL; + + mono_debugger_lock (); + minfo = mono_debug_lookup_method_internal (method); + if (!minfo || !minfo->handle) { + mono_debugger_unlock (); + return NULL; + } + + if (minfo->handle->ppdb) + res = mono_ppdb_lookup_method_async_debug_info (minfo); + + mono_debugger_unlock (); + + return res; +} + +/* + * mono_debug_free_method_async_debug_info: + * + * Free all the data allocated by mono_debug_lookup_method_async_debug_info (). + */ +void +mono_debug_free_method_async_debug_info (MonoDebugMethodAsyncInfo *info) +{ + if (info->num_awaits) { + g_free (info->yield_offsets); + g_free (info->resume_offsets); + g_free (info->move_next_method_token); + } + g_free (info); +} + /** * mono_debug_free_source_location: - * @location: A `MonoDebugSourceLocation'. - * - * Frees the @location. + * \param location A \c MonoDebugSourceLocation + * Frees the \p location. */ void mono_debug_free_source_location (MonoDebugSourceLocation *location) @@ -856,11 +953,18 @@ mono_debug_free_source_location (MonoDebugSourceLocation *location) } } +static int (*get_seq_point) (MonoDomain *domain, MonoMethod *method, gint32 native_offset); + +void +mono_install_get_seq_point (MonoGetSeqPointFunc func) +{ + get_seq_point = func; +} + /** * mono_debug_print_stack_frame: - * @native_offset: Native offset within the @method's machine code. - * - * Conventient wrapper around mono_debug_lookup_source_location() which can be + * \param native_offset Native offset within the \p method's machine code. + * Conventient wrapper around \c mono_debug_lookup_source_location which can be * used if you only want to use the location to print a stack frame. */ gchar * @@ -886,10 +990,22 @@ mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDom offset = -1; } + if (offset < 0 && get_seq_point) + offset = get_seq_point (domain, method, native_offset); + 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); + else { + char *mvid = mono_guid_to_string_minimal ((uint8_t*)method->klass->image->heap_guid.data); + char *aotid = mono_runtime_get_aotid (); + if (aotid) + res = g_strdup_printf ("at %s [0x%05x] in <%s#%s>:0" , fname, offset, mvid, aotid); + else + res = g_strdup_printf ("at %s [0x%05x] in <%s>:0" , fname, offset, mvid); + + g_free (aotid); + g_free (mvid); + } g_free (fname); return res; } @@ -929,6 +1045,9 @@ struct _BundledSymfile { static BundledSymfile *bundled_symfiles = NULL; +/** + * mono_register_symfile_for_assembly: + */ void mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size) {