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)
10 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
14 #include <mono/metadata/assembly.h>
15 #include <mono/metadata/tabledefs.h>
16 #include <mono/metadata/tokentype.h>
17 #include <mono/metadata/appdomain.h>
18 #include <mono/metadata/class-internals.h>
19 #include <mono/metadata/mono-debug.h>
20 #include <mono/metadata/mono-debug-debugger.h>
21 #include <mono/metadata/mono-endian.h>
22 #include <mono/metadata/gc-internals.h>
23 #include <mono/metadata/mempool.h>
24 #include <mono/metadata/debug-mono-ppdb.h>
27 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
29 #if NO_UNALIGNED_ACCESS
30 #define WRITE_UNALIGNED(type, addr, val) \
31 memcpy(addr, &val, sizeof(type))
32 #define READ_UNALIGNED(type, addr, val) \
33 memcpy(&val, addr, sizeof(type))
35 #define WRITE_UNALIGNED(type, addr, val) \
36 (*(type *)(addr) = (val))
37 #define READ_UNALIGNED(type, addr, val) \
38 val = (*(type *)(addr))
41 /* This contains per-domain info */
42 struct _MonoDebugDataTable {
44 GHashTable *method_address_hash;
47 /* This contains JIT debugging information about a method in serialized format */
48 struct _MonoDebugMethodAddress {
49 const guint8 *code_start;
51 guint8 data [MONO_ZERO_LEN_ARRAY];
54 static MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
56 static gboolean mono_debug_initialized = FALSE;
57 /* Maps MonoImage -> MonoMonoDebugHandle */
58 static GHashTable *mono_debug_handles;
59 /* Maps MonoDomain -> MonoDataTable */
60 static GHashTable *data_table_hash;
62 static mono_mutex_t debugger_lock_mutex;
64 static gboolean is_attached = FALSE;
66 static MonoDebugHandle *mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size);
68 static MonoDebugHandle *mono_debug_get_image (MonoImage *image);
69 static void mono_debug_add_assembly (MonoAssembly *assembly,
72 static MonoDebugHandle *open_symfile_from_bundle (MonoImage *image);
74 static MonoDebugDataTable *
75 create_data_table (MonoDomain *domain)
77 MonoDebugDataTable *table;
79 table = g_new0 (MonoDebugDataTable, 1);
81 table->mp = mono_mempool_new ();
82 table->method_address_hash = g_hash_table_new (NULL, NULL);
85 g_hash_table_insert (data_table_hash, domain, table);
91 free_data_table (MonoDebugDataTable *table)
93 mono_mempool_destroy (table->mp);
94 g_hash_table_destroy (table->method_address_hash);
99 static MonoDebugDataTable *
100 lookup_data_table (MonoDomain *domain)
102 MonoDebugDataTable *table;
104 table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain);
106 g_error ("lookup_data_table () failed for %p\n", domain);
113 free_debug_handle (MonoDebugHandle *handle)
116 mono_ppdb_close (handle);
118 mono_debug_close_mono_symbol_file (handle->symfile);
119 /* decrease the refcount added with mono_image_addref () */
120 mono_image_close (handle->image);
125 * Initialize debugging support.
127 * This method must be called after loading corlib,
128 * but before opening the application's main assembly because we need to set some
132 mono_debug_init (MonoDebugFormat format)
134 g_assert (!mono_debug_initialized);
135 if (format == MONO_DEBUG_FORMAT_DEBUGGER)
136 g_error ("The mdb debugger is no longer supported.");
138 mono_debug_initialized = TRUE;
139 mono_debug_format = format;
141 mono_os_mutex_init_recursive (&debugger_lock_mutex);
143 mono_debugger_lock ();
145 mono_debug_handles = g_hash_table_new_full
146 (NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
148 data_table_hash = g_hash_table_new_full (
149 NULL, NULL, NULL, (GDestroyNotify) free_data_table);
151 mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
153 mono_debugger_unlock ();
157 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
159 if (!mono_debug_initialized)
162 mono_debug_open_image (image, raw_contents, size);
166 mono_debug_cleanup (void)
168 if (mono_debug_handles)
169 g_hash_table_destroy (mono_debug_handles);
170 mono_debug_handles = NULL;
172 if (data_table_hash) {
173 g_hash_table_destroy (data_table_hash);
174 data_table_hash = NULL;
179 mono_debug_domain_create (MonoDomain *domain)
181 if (!mono_debug_initialized)
184 mono_debugger_lock ();
186 create_data_table (domain);
188 mono_debugger_unlock ();
192 mono_debug_domain_unload (MonoDomain *domain)
194 MonoDebugDataTable *table;
196 if (!mono_debug_initialized)
199 mono_debugger_lock ();
201 table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain);
203 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
204 domain, mono_domain_get_id (domain));
205 mono_debugger_unlock ();
209 g_hash_table_remove (data_table_hash, domain);
211 mono_debugger_unlock ();
215 * LOCKING: Assumes the debug lock is held.
217 static MonoDebugHandle *
218 mono_debug_get_image (MonoImage *image)
220 return (MonoDebugHandle *)g_hash_table_lookup (mono_debug_handles, image);
224 mono_debug_close_image (MonoImage *image)
226 MonoDebugHandle *handle;
228 if (!mono_debug_initialized)
231 mono_debugger_lock ();
233 handle = mono_debug_get_image (image);
235 mono_debugger_unlock ();
239 g_hash_table_remove (mono_debug_handles, image);
241 mono_debugger_unlock ();
244 static MonoDebugHandle *
245 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
247 MonoDebugHandle *handle;
249 if (mono_image_is_dynamic (image))
252 mono_debugger_lock ();
254 handle = mono_debug_get_image (image);
255 if (handle != NULL) {
256 mono_debugger_unlock ();
260 handle = g_new0 (MonoDebugHandle, 1);
262 handle->image = image;
263 mono_image_addref (image);
265 /* Try a ppdb file first */
266 handle->ppdb = mono_ppdb_load_file (handle->image, raw_contents, size);
269 handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, FALSE);
271 g_hash_table_insert (mono_debug_handles, image, handle);
273 mono_debugger_unlock ();
279 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
281 MonoDebugHandle *handle;
284 mono_debugger_lock ();
285 image = mono_assembly_get_image (assembly);
286 handle = open_symfile_from_bundle (image);
288 mono_debug_open_image (image, NULL, 0);
289 mono_debugger_unlock ();
292 struct LookupMethodData
294 MonoDebugMethodInfo *minfo;
299 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
301 MonoDebugHandle *handle = (MonoDebugHandle *) value;
302 struct LookupMethodData *data = (struct LookupMethodData *) user_data;
308 data->minfo = mono_ppdb_lookup_method (handle, data->method);
309 else if (handle->symfile)
310 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
313 static MonoDebugMethodInfo *
314 mono_debug_lookup_method_internal (MonoMethod *method)
316 struct LookupMethodData data;
319 data.method = method;
321 if (!mono_debug_handles)
324 g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
329 * mono_debug_lookup_method:
331 * Lookup symbol file information for the method @method. The returned
332 * `MonoDebugMethodInfo' is a private structure, but it can be passed to
333 * mono_debug_symfile_lookup_location().
335 MonoDebugMethodInfo *
336 mono_debug_lookup_method (MonoMethod *method)
338 MonoDebugMethodInfo *minfo;
340 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
343 mono_debugger_lock ();
344 minfo = mono_debug_lookup_method_internal (method);
345 mono_debugger_unlock ();
356 lookup_image_func (gpointer key, gpointer value, gpointer user_data)
358 MonoDebugHandle *handle = (MonoDebugHandle *) value;
359 LookupImageData *data = (LookupImageData *) user_data;
364 if (handle->image == data->image && handle->symfile)
369 mono_debug_image_has_debug_info (MonoImage *image)
371 LookupImageData data;
373 if (!mono_debug_handles)
376 memset (&data, 0, sizeof (data));
379 mono_debugger_lock ();
380 g_hash_table_foreach (mono_debug_handles, lookup_image_func, &data);
381 mono_debugger_unlock ();
386 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
389 guint8 byte = value & 0x7f;
400 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
405 guint8 byte = value & 0x7f;
408 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
419 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
421 write_leb128 (var->index, ptr, &ptr);
422 write_sleb128 (var->offset, ptr, &ptr);
423 write_leb128 (var->size, ptr, &ptr);
424 write_leb128 (var->begin_scope, ptr, &ptr);
425 write_leb128 (var->end_scope, ptr, &ptr);
426 WRITE_UNALIGNED (gpointer, ptr, var->type);
427 ptr += sizeof (gpointer);
431 MonoDebugMethodAddress *
432 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
434 MonoDebugDataTable *table;
435 MonoDebugMethodAddress *address;
436 guint8 buffer [BUFSIZ];
437 guint8 *ptr, *oldptr;
438 guint32 i, size, total_size, max_size;
440 mono_debugger_lock ();
442 table = lookup_data_table (domain);
444 max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
445 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
447 if (max_size > BUFSIZ)
448 ptr = oldptr = (guint8 *)g_malloc (max_size);
450 ptr = oldptr = buffer;
452 write_leb128 (jit->prologue_end, ptr, &ptr);
453 write_leb128 (jit->epilogue_begin, ptr, &ptr);
455 write_leb128 (jit->num_line_numbers, ptr, &ptr);
456 for (i = 0; i < jit->num_line_numbers; i++) {
457 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
459 write_sleb128 (lne->il_offset, ptr, &ptr);
460 write_sleb128 (lne->native_offset, ptr, &ptr);
463 *ptr++ = jit->this_var ? 1 : 0;
465 write_variable (jit->this_var, ptr, &ptr);
467 write_leb128 (jit->num_params, ptr, &ptr);
468 for (i = 0; i < jit->num_params; i++)
469 write_variable (&jit->params [i], ptr, &ptr);
471 write_leb128 (jit->num_locals, ptr, &ptr);
472 for (i = 0; i < jit->num_locals; i++)
473 write_variable (&jit->locals [i], ptr, &ptr);
475 *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
476 if (jit->gsharedvt_info_var) {
477 write_variable (jit->gsharedvt_info_var, ptr, &ptr);
478 write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
482 g_assert (size < max_size);
483 total_size = size + sizeof (MonoDebugMethodAddress);
485 if (method_is_dynamic (method)) {
486 address = (MonoDebugMethodAddress *)g_malloc0 (total_size);
488 address = (MonoDebugMethodAddress *)mono_mempool_alloc (table->mp, total_size);
491 address->code_start = jit->code_start;
492 address->code_size = jit->code_size;
494 memcpy (&address->data, oldptr, size);
495 if (max_size > BUFSIZ)
498 g_hash_table_insert (table->method_address_hash, method, address);
500 mono_debugger_unlock ();
505 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
507 MonoDebugDataTable *table;
508 MonoDebugMethodAddress *address;
510 if (!mono_debug_initialized)
513 g_assert (method_is_dynamic (method));
515 mono_debugger_lock ();
517 table = lookup_data_table (domain);
519 address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
523 g_hash_table_remove (table->method_address_hash, method);
525 mono_debugger_unlock ();
529 mono_debug_add_delegate_trampoline (gpointer code, int size)
533 static inline guint32
534 read_leb128 (guint8 *ptr, guint8 **rptr)
536 guint32 result = 0, shift = 0;
539 guint8 byte = *ptr++;
541 result |= (byte & 0x7f) << shift;
542 if ((byte & 0x80) == 0)
552 read_sleb128 (guint8 *ptr, guint8 **rptr)
558 guint8 byte = *ptr++;
560 result |= (byte & 0x7f) << shift;
566 if ((shift < 32) && (byte & 0x40))
567 result |= - (1 << shift);
576 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
578 var->index = read_leb128 (ptr, &ptr);
579 var->offset = read_sleb128 (ptr, &ptr);
580 var->size = read_leb128 (ptr, &ptr);
581 var->begin_scope = read_leb128 (ptr, &ptr);
582 var->end_scope = read_leb128 (ptr, &ptr);
583 READ_UNALIGNED (MonoType *, ptr, var->type);
584 ptr += sizeof (gpointer);
589 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
593 g_free (jit->line_numbers);
594 g_free (jit->this_var);
595 g_free (jit->params);
596 g_free (jit->locals);
597 g_free (jit->gsharedvt_info_var);
598 g_free (jit->gsharedvt_locals_var);
602 static MonoDebugMethodJitInfo *
603 mono_debug_read_method (MonoDebugMethodAddress *address)
605 MonoDebugMethodJitInfo *jit;
609 jit = g_new0 (MonoDebugMethodJitInfo, 1);
610 jit->code_start = address->code_start;
611 jit->code_size = address->code_size;
613 ptr = (guint8 *) &address->data;
615 jit->prologue_end = read_leb128 (ptr, &ptr);
616 jit->epilogue_begin = read_leb128 (ptr, &ptr);
618 jit->num_line_numbers = read_leb128 (ptr, &ptr);
619 jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
620 for (i = 0; i < jit->num_line_numbers; i++) {
621 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
623 lne->il_offset = read_sleb128 (ptr, &ptr);
624 lne->native_offset = read_sleb128 (ptr, &ptr);
628 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
629 read_variable (jit->this_var, ptr, &ptr);
632 jit->num_params = read_leb128 (ptr, &ptr);
633 jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
634 for (i = 0; i < jit->num_params; i++)
635 read_variable (&jit->params [i], ptr, &ptr);
637 jit->num_locals = read_leb128 (ptr, &ptr);
638 jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
639 for (i = 0; i < jit->num_locals; i++)
640 read_variable (&jit->locals [i], ptr, &ptr);
643 jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
644 jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
645 read_variable (jit->gsharedvt_info_var, ptr, &ptr);
646 read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
652 static MonoDebugMethodJitInfo *
653 find_method (MonoMethod *method, MonoDomain *domain)
655 MonoDebugDataTable *table;
656 MonoDebugMethodAddress *address;
658 table = lookup_data_table (domain);
659 address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
664 return mono_debug_read_method (address);
667 MonoDebugMethodJitInfo *
668 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
670 MonoDebugMethodJitInfo *res;
672 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
675 mono_debugger_lock ();
676 res = find_method (method, domain);
677 mono_debugger_unlock ();
681 MonoDebugMethodAddressList *
682 mono_debug_lookup_method_addresses (MonoMethod *method)
684 g_assert_not_reached ();
689 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
691 MonoDebugMethodJitInfo *jit;
694 jit = find_method (method, domain);
695 if (!jit || !jit->line_numbers)
696 goto cleanup_and_fail;
698 for (i = jit->num_line_numbers - 1; i >= 0; i--) {
699 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
701 if (lne.native_offset <= native_offset) {
702 mono_debug_free_method_jit_info (jit);
703 return lne.il_offset;
708 mono_debug_free_method_jit_info (jit);
713 * mono_debug_il_offset_from_address:
715 * Compute the IL offset corresponding to NATIVE_OFFSET inside the native
716 * code of METHOD in DOMAIN.
719 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
723 mono_debugger_lock ();
725 res = il_offset_from_address (method, domain, native_offset);
727 mono_debugger_unlock ();
733 * mono_debug_lookup_source_location:
734 * @address: Native offset within the @method's machine code.
736 * Lookup the source code corresponding to the machine instruction located at
737 * native offset @address within @method.
739 * The returned `MonoDebugSourceLocation' contains both file / line number
740 * information and the corresponding IL offset. It must be freed by
741 * mono_debug_free_source_location().
743 MonoDebugSourceLocation *
744 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
746 MonoDebugMethodInfo *minfo;
747 MonoDebugSourceLocation *location;
750 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
753 mono_debugger_lock ();
754 minfo = mono_debug_lookup_method_internal (method);
755 if (!minfo || !minfo->handle) {
756 mono_debugger_unlock ();
760 if (!minfo->handle->ppdb && (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))) {
761 mono_debugger_unlock ();
765 offset = il_offset_from_address (method, domain, address);
767 mono_debugger_unlock ();
771 if (minfo->handle->ppdb)
772 location = mono_ppdb_lookup_location (minfo, offset);
774 location = mono_debug_symfile_lookup_location (minfo, offset);
775 mono_debugger_unlock ();
779 MonoDebugSourceLocation *
780 mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset)
782 MonoDebugSourceLocation *location;
784 mono_debugger_lock ();
785 if (minfo->handle->ppdb)
786 location = mono_ppdb_lookup_location (minfo, il_offset);
788 location = mono_debug_symfile_lookup_location (minfo, il_offset);
789 mono_debugger_unlock ();
794 * mono_debug_lookup_locals:
796 * Return information about the local variables of MINFO.
797 * The result should be freed using mono_debug_free_locals ().
800 mono_debug_lookup_locals (MonoMethod *method)
802 MonoDebugMethodInfo *minfo;
803 MonoDebugLocalsInfo *res;
805 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
808 mono_debugger_lock ();
809 minfo = mono_debug_lookup_method_internal (method);
810 if (!minfo || !minfo->handle) {
811 mono_debugger_unlock ();
815 if (minfo->handle->ppdb) {
816 res = mono_ppdb_lookup_locals (minfo);
818 if (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))
821 res = mono_debug_symfile_lookup_locals (minfo);
823 mono_debugger_unlock ();
829 * mono_debug_free_locals:
831 * Free all the data allocated by mono_debug_lookup_locals ().
834 mono_debug_free_locals (MonoDebugLocalsInfo *info)
838 for (i = 0; i < info->num_locals; ++i)
839 g_free (info->locals [i].name);
840 g_free (info->locals);
841 g_free (info->code_blocks);
846 * mono_debug_free_source_location:
847 * @location: A `MonoDebugSourceLocation'.
849 * Frees the @location.
852 mono_debug_free_source_location (MonoDebugSourceLocation *location)
855 g_free (location->source_file);
861 * mono_debug_print_stack_frame:
862 * @native_offset: Native offset within the @method's machine code.
864 * Conventient wrapper around mono_debug_lookup_source_location() which can be
865 * used if you only want to use the location to print a stack frame.
868 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
870 MonoDebugSourceLocation *location;
871 gchar *fname, *ptr, *res;
874 fname = mono_method_full_name (method, TRUE);
875 for (ptr = fname; *ptr; ptr++) {
876 if (*ptr == ':') *ptr = '.';
879 location = mono_debug_lookup_source_location (method, native_offset, domain);
882 if (mono_debug_initialized) {
883 mono_debugger_lock ();
884 offset = il_offset_from_address (method, domain, native_offset);
885 mono_debugger_unlock ();
891 res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
893 res = g_strdup_printf ("at %s <IL 0x%05x, 0x%05x>", fname, offset, native_offset);
898 res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
899 location->source_file, location->row);
902 mono_debug_free_source_location (location);
907 mono_set_is_debugger_attached (gboolean attached)
909 is_attached = attached;
913 mono_is_debugger_attached (void)
922 typedef struct _BundledSymfile BundledSymfile;
924 struct _BundledSymfile {
925 BundledSymfile *next;
927 const mono_byte *raw_contents;
931 static BundledSymfile *bundled_symfiles = NULL;
934 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
936 BundledSymfile *bsymfile;
938 bsymfile = g_new0 (BundledSymfile, 1);
939 bsymfile->aname = assembly_name;
940 bsymfile->raw_contents = raw_contents;
941 bsymfile->size = size;
942 bsymfile->next = bundled_symfiles;
943 bundled_symfiles = bsymfile;
946 static MonoDebugHandle *
947 open_symfile_from_bundle (MonoImage *image)
949 BundledSymfile *bsymfile;
951 for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
952 if (strcmp (bsymfile->aname, image->module_name))
955 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
962 mono_debugger_lock (void)
964 g_assert (mono_debug_initialized);
965 mono_os_mutex_lock (&debugger_lock_mutex);
969 mono_debugger_unlock (void)
971 g_assert (mono_debug_initialized);
972 mono_os_mutex_unlock (&debugger_lock_mutex);
976 * mono_debug_enabled:
978 * Returns true is debug information is enabled. This doesn't relate if a debugger is present or not.
981 mono_debug_enabled (void)
983 return mono_debug_format != MONO_DEBUG_FORMAT_NONE;
987 mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
989 if (minfo->handle->ppdb)
990 mono_ppdb_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);
992 mono_debug_symfile_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);