5 * Mono Project (http://www.mono-project.com)
7 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
8 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
13 #include <mono/metadata/assembly.h>
14 #include <mono/metadata/tabledefs.h>
15 #include <mono/metadata/tokentype.h>
16 #include <mono/metadata/appdomain.h>
17 #include <mono/metadata/class-internals.h>
18 #include <mono/metadata/mono-debug.h>
19 #include <mono/metadata/mono-debug-debugger.h>
20 #include <mono/metadata/mono-endian.h>
21 #include <mono/metadata/gc-internal.h>
22 #include <mono/metadata/mempool.h>
25 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
27 #if NO_UNALIGNED_ACCESS
28 #define WRITE_UNALIGNED(type, addr, val) \
29 memcpy(addr, &val, sizeof(type))
30 #define READ_UNALIGNED(type, addr, val) \
31 memcpy(&val, addr, sizeof(type))
33 #define WRITE_UNALIGNED(type, addr, val) \
34 (*(type *)(addr) = (val))
35 #define READ_UNALIGNED(type, addr, val) \
36 val = (*(type *)(addr))
39 /* This contains per-domain info */
40 struct _MonoDebugDataTable {
42 GHashTable *method_address_hash;
45 /* This contains JIT debugging information about a method in serialized format */
46 struct _MonoDebugMethodAddress {
47 const guint8 *code_start;
49 guint8 data [MONO_ZERO_LEN_ARRAY];
52 static MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
54 static gboolean mono_debug_initialized = FALSE;
55 /* Maps MonoImage -> MonoMonoDebugHandle */
56 static GHashTable *mono_debug_handles;
57 /* Maps MonoDomain -> MonoDataTable */
58 static GHashTable *data_table_hash;
60 static mono_mutex_t debugger_lock_mutex;
62 static int initialized = 0;
63 static gboolean is_attached = FALSE;
65 static MonoDebugHandle *mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size);
67 static MonoDebugHandle *mono_debug_get_image (MonoImage *image);
68 static void mono_debug_add_assembly (MonoAssembly *assembly,
71 static MonoDebugHandle *open_symfile_from_bundle (MonoImage *image);
73 static MonoDebugDataTable *
74 create_data_table (MonoDomain *domain)
76 MonoDebugDataTable *table;
78 table = g_new0 (MonoDebugDataTable, 1);
80 table->mp = mono_mempool_new ();
81 table->method_address_hash = g_hash_table_new (NULL, NULL);
84 g_hash_table_insert (data_table_hash, domain, table);
90 free_data_table (MonoDebugDataTable *table)
92 mono_mempool_destroy (table->mp);
93 g_hash_table_destroy (table->method_address_hash);
98 static MonoDebugDataTable *
99 lookup_data_table (MonoDomain *domain)
101 MonoDebugDataTable *table;
103 table = g_hash_table_lookup (data_table_hash, domain);
105 g_error ("lookup_data_table () failed for %p\n", domain);
112 free_debug_handle (MonoDebugHandle *handle)
115 mono_debug_close_mono_symbol_file (handle->symfile);
116 /* decrease the refcount added with mono_image_addref () */
117 mono_image_close (handle->image);
122 * Initialize debugging support.
124 * This method must be called after loading corlib,
125 * but before opening the application's main assembly because we need to set some
129 mono_debug_init (MonoDebugFormat format)
131 g_assert (!mono_debug_initialized);
132 if (format == MONO_DEBUG_FORMAT_DEBUGGER)
133 g_error ("The mdb debugger is no longer supported.");
135 mono_debug_initialized = TRUE;
136 mono_debug_format = format;
138 mono_debugger_initialize ();
140 mono_debugger_lock ();
142 mono_debug_handles = g_hash_table_new_full
143 (NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
145 data_table_hash = g_hash_table_new_full (
146 NULL, NULL, NULL, (GDestroyNotify) free_data_table);
148 mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
150 mono_debugger_unlock ();
154 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
156 if (!mono_debug_initialized)
159 mono_debug_open_image (image, raw_contents, size);
163 mono_debug_cleanup (void)
165 if (mono_debug_handles)
166 g_hash_table_destroy (mono_debug_handles);
167 mono_debug_handles = NULL;
169 if (data_table_hash) {
170 g_hash_table_destroy (data_table_hash);
171 data_table_hash = NULL;
176 mono_debug_domain_create (MonoDomain *domain)
178 if (!mono_debug_initialized)
181 mono_debugger_lock ();
183 create_data_table (domain);
185 mono_debugger_unlock ();
189 mono_debug_domain_unload (MonoDomain *domain)
191 MonoDebugDataTable *table;
193 if (!mono_debug_initialized)
196 mono_debugger_lock ();
198 table = g_hash_table_lookup (data_table_hash, domain);
200 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
201 domain, mono_domain_get_id (domain));
202 mono_debugger_unlock ();
206 g_hash_table_remove (data_table_hash, domain);
208 mono_debugger_unlock ();
212 * LOCKING: Assumes the debug lock is held.
214 static MonoDebugHandle *
215 mono_debug_get_image (MonoImage *image)
217 return g_hash_table_lookup (mono_debug_handles, image);
221 mono_debug_close_image (MonoImage *image)
223 MonoDebugHandle *handle;
225 if (!mono_debug_initialized)
228 mono_debugger_lock ();
230 handle = mono_debug_get_image (image);
232 mono_debugger_unlock ();
236 g_hash_table_remove (mono_debug_handles, image);
238 mono_debugger_unlock ();
241 static MonoDebugHandle *
242 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
244 MonoDebugHandle *handle;
246 if (mono_image_is_dynamic (image))
249 mono_debugger_lock ();
251 handle = mono_debug_get_image (image);
252 if (handle != NULL) {
253 mono_debugger_unlock ();
257 handle = g_new0 (MonoDebugHandle, 1);
259 handle->image = image;
260 mono_image_addref (image);
262 handle->symfile = mono_debug_open_mono_symbols (
263 handle, raw_contents, size, FALSE);
265 g_hash_table_insert (mono_debug_handles, image, handle);
267 mono_debugger_unlock ();
273 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
275 MonoDebugHandle *handle;
278 mono_debugger_lock ();
279 image = mono_assembly_get_image (assembly);
280 handle = open_symfile_from_bundle (image);
282 mono_debug_open_image (image, NULL, 0);
283 mono_debugger_unlock ();
286 struct LookupMethodData
288 MonoDebugMethodInfo *minfo;
293 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
295 MonoDebugHandle *handle = (MonoDebugHandle *) value;
296 struct LookupMethodData *data = (struct LookupMethodData *) user_data;
302 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
305 static MonoDebugMethodInfo *
306 mono_debug_lookup_method_internal (MonoMethod *method)
308 struct LookupMethodData data;
311 data.method = method;
313 if (!mono_debug_handles)
316 g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
321 * mono_debug_lookup_method:
323 * Lookup symbol file information for the method @method. The returned
324 * `MonoDebugMethodInfo' is a private structure, but it can be passed to
325 * mono_debug_symfile_lookup_location().
327 MonoDebugMethodInfo *
328 mono_debug_lookup_method (MonoMethod *method)
330 MonoDebugMethodInfo *minfo;
332 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
335 mono_debugger_lock ();
336 minfo = mono_debug_lookup_method_internal (method);
337 mono_debugger_unlock ();
348 lookup_image_func (gpointer key, gpointer value, gpointer user_data)
350 MonoDebugHandle *handle = (MonoDebugHandle *) value;
351 LookupImageData *data = (LookupImageData *) user_data;
356 if (handle->image == data->image && handle->symfile)
361 mono_debug_image_has_debug_info (MonoImage *image)
363 LookupImageData data;
365 if (!mono_debug_handles)
368 memset (&data, 0, sizeof (data));
371 mono_debugger_lock ();
372 g_hash_table_foreach (mono_debug_handles, lookup_image_func, &data);
373 mono_debugger_unlock ();
378 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
381 guint8 byte = value & 0x7f;
392 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
397 guint8 byte = value & 0x7f;
400 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
411 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
413 write_leb128 (var->index, ptr, &ptr);
414 write_sleb128 (var->offset, ptr, &ptr);
415 write_leb128 (var->size, ptr, &ptr);
416 write_leb128 (var->begin_scope, ptr, &ptr);
417 write_leb128 (var->end_scope, ptr, &ptr);
418 WRITE_UNALIGNED (gpointer, ptr, var->type);
419 ptr += sizeof (gpointer);
423 MonoDebugMethodAddress *
424 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
426 MonoDebugDataTable *table;
427 MonoDebugMethodAddress *address;
428 guint8 buffer [BUFSIZ];
429 guint8 *ptr, *oldptr;
430 guint32 i, size, total_size, max_size;
432 mono_debugger_lock ();
434 table = lookup_data_table (domain);
436 max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
437 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
439 if (max_size > BUFSIZ)
440 ptr = oldptr = g_malloc (max_size);
442 ptr = oldptr = buffer;
444 write_leb128 (jit->prologue_end, ptr, &ptr);
445 write_leb128 (jit->epilogue_begin, ptr, &ptr);
447 write_leb128 (jit->num_line_numbers, ptr, &ptr);
448 for (i = 0; i < jit->num_line_numbers; i++) {
449 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
451 write_sleb128 (lne->il_offset, ptr, &ptr);
452 write_sleb128 (lne->native_offset, ptr, &ptr);
455 *ptr++ = jit->this_var ? 1 : 0;
457 write_variable (jit->this_var, ptr, &ptr);
459 write_leb128 (jit->num_params, ptr, &ptr);
460 for (i = 0; i < jit->num_params; i++)
461 write_variable (&jit->params [i], ptr, &ptr);
463 write_leb128 (jit->num_locals, ptr, &ptr);
464 for (i = 0; i < jit->num_locals; i++)
465 write_variable (&jit->locals [i], ptr, &ptr);
467 *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
468 if (jit->gsharedvt_info_var) {
469 write_variable (jit->gsharedvt_info_var, ptr, &ptr);
470 write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
474 g_assert (size < max_size);
475 total_size = size + sizeof (MonoDebugMethodAddress);
477 if (method_is_dynamic (method)) {
478 address = g_malloc0 (total_size);
480 address = mono_mempool_alloc (table->mp, total_size);
483 address->code_start = jit->code_start;
484 address->code_size = jit->code_size;
486 memcpy (&address->data, oldptr, size);
487 if (max_size > BUFSIZ)
490 g_hash_table_insert (table->method_address_hash, method, address);
492 mono_debugger_unlock ();
497 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
499 MonoDebugDataTable *table;
500 MonoDebugMethodAddress *address;
502 if (!mono_debug_initialized)
505 g_assert (method_is_dynamic (method));
507 mono_debugger_lock ();
509 table = lookup_data_table (domain);
511 address = g_hash_table_lookup (table->method_address_hash, method);
515 g_hash_table_remove (table->method_address_hash, method);
517 mono_debugger_unlock ();
521 mono_debug_add_delegate_trampoline (gpointer code, int size)
525 static inline guint32
526 read_leb128 (guint8 *ptr, guint8 **rptr)
528 guint32 result = 0, shift = 0;
531 guint8 byte = *ptr++;
533 result |= (byte & 0x7f) << shift;
534 if ((byte & 0x80) == 0)
544 read_sleb128 (guint8 *ptr, guint8 **rptr)
550 guint8 byte = *ptr++;
552 result |= (byte & 0x7f) << shift;
558 if ((shift < 32) && (byte & 0x40))
559 result |= - (1 << shift);
568 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
570 var->index = read_leb128 (ptr, &ptr);
571 var->offset = read_sleb128 (ptr, &ptr);
572 var->size = read_leb128 (ptr, &ptr);
573 var->begin_scope = read_leb128 (ptr, &ptr);
574 var->end_scope = read_leb128 (ptr, &ptr);
575 READ_UNALIGNED (gpointer, ptr, var->type);
576 ptr += sizeof (gpointer);
581 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
585 g_free (jit->line_numbers);
586 g_free (jit->this_var);
587 g_free (jit->params);
588 g_free (jit->locals);
589 g_free (jit->gsharedvt_info_var);
590 g_free (jit->gsharedvt_locals_var);
594 static MonoDebugMethodJitInfo *
595 mono_debug_read_method (MonoDebugMethodAddress *address)
597 MonoDebugMethodJitInfo *jit;
601 jit = g_new0 (MonoDebugMethodJitInfo, 1);
602 jit->code_start = address->code_start;
603 jit->code_size = address->code_size;
605 ptr = (guint8 *) &address->data;
607 jit->prologue_end = read_leb128 (ptr, &ptr);
608 jit->epilogue_begin = read_leb128 (ptr, &ptr);
610 jit->num_line_numbers = read_leb128 (ptr, &ptr);
611 jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
612 for (i = 0; i < jit->num_line_numbers; i++) {
613 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
615 lne->il_offset = read_sleb128 (ptr, &ptr);
616 lne->native_offset = read_sleb128 (ptr, &ptr);
620 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
621 read_variable (jit->this_var, ptr, &ptr);
624 jit->num_params = read_leb128 (ptr, &ptr);
625 jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
626 for (i = 0; i < jit->num_params; i++)
627 read_variable (&jit->params [i], ptr, &ptr);
629 jit->num_locals = read_leb128 (ptr, &ptr);
630 jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
631 for (i = 0; i < jit->num_locals; i++)
632 read_variable (&jit->locals [i], ptr, &ptr);
635 jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
636 jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
637 read_variable (jit->gsharedvt_info_var, ptr, &ptr);
638 read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
644 static MonoDebugMethodJitInfo *
645 find_method (MonoMethod *method, MonoDomain *domain)
647 MonoDebugDataTable *table;
648 MonoDebugMethodAddress *address;
650 table = lookup_data_table (domain);
651 address = g_hash_table_lookup (table->method_address_hash, method);
656 return mono_debug_read_method (address);
659 MonoDebugMethodJitInfo *
660 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
662 MonoDebugMethodJitInfo *res;
664 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
667 mono_debugger_lock ();
668 res = find_method (method, domain);
669 mono_debugger_unlock ();
673 MonoDebugMethodAddressList *
674 mono_debug_lookup_method_addresses (MonoMethod *method)
676 g_assert_not_reached ();
681 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
683 MonoDebugMethodJitInfo *jit;
686 jit = find_method (method, domain);
687 if (!jit || !jit->line_numbers)
688 goto cleanup_and_fail;
690 for (i = jit->num_line_numbers - 1; i >= 0; i--) {
691 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
693 if (lne.native_offset <= native_offset) {
694 mono_debug_free_method_jit_info (jit);
695 return lne.il_offset;
700 mono_debug_free_method_jit_info (jit);
705 * mono_debug_il_offset_from_address:
707 * Compute the IL offset corresponding to NATIVE_OFFSET inside the native
708 * code of METHOD in DOMAIN.
711 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
715 mono_debugger_lock ();
717 res = il_offset_from_address (method, domain, native_offset);
719 mono_debugger_unlock ();
725 * mono_debug_lookup_source_location:
726 * @address: Native offset within the @method's machine code.
728 * Lookup the source code corresponding to the machine instruction located at
729 * native offset @address within @method.
731 * The returned `MonoDebugSourceLocation' contains both file / line number
732 * information and the corresponding IL offset. It must be freed by
733 * mono_debug_free_source_location().
735 MonoDebugSourceLocation *
736 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
738 MonoDebugMethodInfo *minfo;
739 MonoDebugSourceLocation *location;
742 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
745 mono_debugger_lock ();
746 minfo = mono_debug_lookup_method_internal (method);
747 if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
748 mono_debugger_unlock ();
752 offset = il_offset_from_address (method, domain, address);
754 mono_debugger_unlock ();
758 location = mono_debug_symfile_lookup_location (minfo, offset);
759 mono_debugger_unlock ();
764 * mono_debug_lookup_locals:
766 * Return information about the local variables of MINFO.
767 * The result should be freed using mono_debug_symfile_free_locals ().
770 mono_debug_lookup_locals (MonoMethod *method)
772 MonoDebugMethodInfo *minfo;
773 MonoDebugLocalsInfo *res;
775 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
778 mono_debugger_lock ();
779 minfo = mono_debug_lookup_method_internal (method);
780 if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
781 mono_debugger_unlock ();
785 res = mono_debug_symfile_lookup_locals (minfo);
786 mono_debugger_unlock ();
792 * mono_debug_free_source_location:
793 * @location: A `MonoDebugSourceLocation'.
795 * Frees the @location.
798 mono_debug_free_source_location (MonoDebugSourceLocation *location)
801 g_free (location->source_file);
807 * mono_debug_print_stack_frame:
808 * @native_offset: Native offset within the @method's machine code.
810 * Conventient wrapper around mono_debug_lookup_source_location() which can be
811 * used if you only want to use the location to print a stack frame.
814 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
816 MonoDebugSourceLocation *location;
817 gchar *fname, *ptr, *res;
820 fname = mono_method_full_name (method, TRUE);
821 for (ptr = fname; *ptr; ptr++) {
822 if (*ptr == ':') *ptr = '.';
825 location = mono_debug_lookup_source_location (method, native_offset, domain);
828 if (mono_debug_initialized) {
829 mono_debugger_lock ();
830 offset = il_offset_from_address (method, domain, native_offset);
831 mono_debugger_unlock ();
837 res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
839 res = g_strdup_printf ("at %s <IL 0x%05x, 0x%05x>", fname, offset, native_offset);
844 res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
845 location->source_file, location->row);
848 mono_debug_free_source_location (location);
853 mono_set_is_debugger_attached (gboolean attached)
855 is_attached = attached;
859 mono_is_debugger_attached (void)
868 typedef struct _BundledSymfile BundledSymfile;
870 struct _BundledSymfile {
871 BundledSymfile *next;
873 const mono_byte *raw_contents;
877 static BundledSymfile *bundled_symfiles = NULL;
880 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
882 BundledSymfile *bsymfile;
884 bsymfile = g_new0 (BundledSymfile, 1);
885 bsymfile->aname = assembly_name;
886 bsymfile->raw_contents = raw_contents;
887 bsymfile->size = size;
888 bsymfile->next = bundled_symfiles;
889 bundled_symfiles = bsymfile;
892 static MonoDebugHandle *
893 open_symfile_from_bundle (MonoImage *image)
895 BundledSymfile *bsymfile;
897 for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
898 if (strcmp (bsymfile->aname, image->module_name))
901 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
908 mono_debugger_lock (void)
910 g_assert (initialized);
911 mono_mutex_lock (&debugger_lock_mutex);
915 mono_debugger_unlock (void)
917 g_assert (initialized);
918 mono_mutex_unlock (&debugger_lock_mutex);
922 mono_debugger_initialize ()
924 mono_mutex_init_recursive (&debugger_lock_mutex);
929 * mono_debug_enabled:
931 * Returns true is debug information is enabled. This doesn't relate if a debugger is present or not.
934 mono_debug_enabled (void)
936 return mono_debug_format != MONO_DEBUG_FORMAT_NONE;