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-internals.h>
22 #include <mono/metadata/mempool.h>
23 #include <mono/metadata/debug-mono-ppdb.h>
26 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
28 #if NO_UNALIGNED_ACCESS
29 #define WRITE_UNALIGNED(type, addr, val) \
30 memcpy(addr, &val, sizeof(type))
31 #define READ_UNALIGNED(type, addr, val) \
32 memcpy(&val, addr, sizeof(type))
34 #define WRITE_UNALIGNED(type, addr, val) \
35 (*(type *)(addr) = (val))
36 #define READ_UNALIGNED(type, addr, val) \
37 val = (*(type *)(addr))
40 /* This contains per-domain info */
41 struct _MonoDebugDataTable {
43 GHashTable *method_address_hash;
46 /* This contains JIT debugging information about a method in serialized format */
47 struct _MonoDebugMethodAddress {
48 const guint8 *code_start;
50 guint8 data [MONO_ZERO_LEN_ARRAY];
53 static MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
55 static gboolean mono_debug_initialized = FALSE;
56 /* Maps MonoImage -> MonoMonoDebugHandle */
57 static GHashTable *mono_debug_handles;
58 /* Maps MonoDomain -> MonoDataTable */
59 static GHashTable *data_table_hash;
61 static mono_mutex_t debugger_lock_mutex;
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 = (MonoDebugDataTable *)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_ppdb_close (handle);
117 mono_debug_close_mono_symbol_file (handle->symfile);
118 /* decrease the refcount added with mono_image_addref () */
119 mono_image_close (handle->image);
124 * Initialize debugging support.
126 * This method must be called after loading corlib,
127 * but before opening the application's main assembly because we need to set some
131 mono_debug_init (MonoDebugFormat format)
133 g_assert (!mono_debug_initialized);
134 if (format == MONO_DEBUG_FORMAT_DEBUGGER)
135 g_error ("The mdb debugger is no longer supported.");
137 mono_debug_initialized = TRUE;
138 mono_debug_format = format;
140 mono_os_mutex_init_recursive (&debugger_lock_mutex);
142 mono_debugger_lock ();
144 mono_debug_handles = g_hash_table_new_full
145 (NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
147 data_table_hash = g_hash_table_new_full (
148 NULL, NULL, NULL, (GDestroyNotify) free_data_table);
150 mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
152 mono_debugger_unlock ();
156 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
158 if (!mono_debug_initialized)
161 mono_debug_open_image (image, raw_contents, size);
165 mono_debug_cleanup (void)
167 if (mono_debug_handles)
168 g_hash_table_destroy (mono_debug_handles);
169 mono_debug_handles = NULL;
171 if (data_table_hash) {
172 g_hash_table_destroy (data_table_hash);
173 data_table_hash = NULL;
178 mono_debug_domain_create (MonoDomain *domain)
180 if (!mono_debug_initialized)
183 mono_debugger_lock ();
185 create_data_table (domain);
187 mono_debugger_unlock ();
191 mono_debug_domain_unload (MonoDomain *domain)
193 MonoDebugDataTable *table;
195 if (!mono_debug_initialized)
198 mono_debugger_lock ();
200 table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain);
202 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
203 domain, mono_domain_get_id (domain));
204 mono_debugger_unlock ();
208 g_hash_table_remove (data_table_hash, domain);
210 mono_debugger_unlock ();
214 * LOCKING: Assumes the debug lock is held.
216 static MonoDebugHandle *
217 mono_debug_get_image (MonoImage *image)
219 return (MonoDebugHandle *)g_hash_table_lookup (mono_debug_handles, image);
223 mono_debug_close_image (MonoImage *image)
225 MonoDebugHandle *handle;
227 if (!mono_debug_initialized)
230 mono_debugger_lock ();
232 handle = mono_debug_get_image (image);
234 mono_debugger_unlock ();
238 g_hash_table_remove (mono_debug_handles, image);
240 mono_debugger_unlock ();
243 static MonoDebugHandle *
244 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
246 MonoDebugHandle *handle;
248 if (mono_image_is_dynamic (image))
251 mono_debugger_lock ();
253 handle = mono_debug_get_image (image);
254 if (handle != NULL) {
255 mono_debugger_unlock ();
259 handle = g_new0 (MonoDebugHandle, 1);
261 handle->image = image;
262 mono_image_addref (image);
264 /* Try a ppdb file first */
265 handle->ppdb = mono_ppdb_load_file (handle->image, raw_contents, size);
268 handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, FALSE);
270 g_hash_table_insert (mono_debug_handles, image, handle);
272 mono_debugger_unlock ();
278 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
280 MonoDebugHandle *handle;
283 mono_debugger_lock ();
284 image = mono_assembly_get_image (assembly);
285 handle = open_symfile_from_bundle (image);
287 mono_debug_open_image (image, NULL, 0);
288 mono_debugger_unlock ();
291 struct LookupMethodData
293 MonoDebugMethodInfo *minfo;
298 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
300 MonoDebugHandle *handle = (MonoDebugHandle *) value;
301 struct LookupMethodData *data = (struct LookupMethodData *) user_data;
307 data->minfo = mono_ppdb_lookup_method (handle, data->method);
308 else if (handle->symfile)
309 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
312 static MonoDebugMethodInfo *
313 mono_debug_lookup_method_internal (MonoMethod *method)
315 struct LookupMethodData data;
318 data.method = method;
320 if (!mono_debug_handles)
323 g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
328 * mono_debug_lookup_method:
330 * Lookup symbol file information for the method @method. The returned
331 * `MonoDebugMethodInfo' is a private structure, but it can be passed to
332 * mono_debug_symfile_lookup_location().
334 MonoDebugMethodInfo *
335 mono_debug_lookup_method (MonoMethod *method)
337 MonoDebugMethodInfo *minfo;
339 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
342 mono_debugger_lock ();
343 minfo = mono_debug_lookup_method_internal (method);
344 mono_debugger_unlock ();
355 lookup_image_func (gpointer key, gpointer value, gpointer user_data)
357 MonoDebugHandle *handle = (MonoDebugHandle *) value;
358 LookupImageData *data = (LookupImageData *) user_data;
363 if (handle->image == data->image && handle->symfile)
368 mono_debug_image_has_debug_info (MonoImage *image)
370 LookupImageData data;
372 if (!mono_debug_handles)
375 memset (&data, 0, sizeof (data));
378 mono_debugger_lock ();
379 g_hash_table_foreach (mono_debug_handles, lookup_image_func, &data);
380 mono_debugger_unlock ();
385 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
388 guint8 byte = value & 0x7f;
399 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
404 guint8 byte = value & 0x7f;
407 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
418 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
420 write_leb128 (var->index, ptr, &ptr);
421 write_sleb128 (var->offset, ptr, &ptr);
422 write_leb128 (var->size, ptr, &ptr);
423 write_leb128 (var->begin_scope, ptr, &ptr);
424 write_leb128 (var->end_scope, ptr, &ptr);
425 WRITE_UNALIGNED (gpointer, ptr, var->type);
426 ptr += sizeof (gpointer);
430 MonoDebugMethodAddress *
431 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
433 MonoDebugDataTable *table;
434 MonoDebugMethodAddress *address;
435 guint8 buffer [BUFSIZ];
436 guint8 *ptr, *oldptr;
437 guint32 i, size, total_size, max_size;
439 mono_debugger_lock ();
441 table = lookup_data_table (domain);
443 max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
444 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
446 if (max_size > BUFSIZ)
447 ptr = oldptr = (guint8 *)g_malloc (max_size);
449 ptr = oldptr = buffer;
451 write_leb128 (jit->prologue_end, ptr, &ptr);
452 write_leb128 (jit->epilogue_begin, ptr, &ptr);
454 write_leb128 (jit->num_line_numbers, ptr, &ptr);
455 for (i = 0; i < jit->num_line_numbers; i++) {
456 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
458 write_sleb128 (lne->il_offset, ptr, &ptr);
459 write_sleb128 (lne->native_offset, ptr, &ptr);
462 *ptr++ = jit->this_var ? 1 : 0;
464 write_variable (jit->this_var, ptr, &ptr);
466 write_leb128 (jit->num_params, ptr, &ptr);
467 for (i = 0; i < jit->num_params; i++)
468 write_variable (&jit->params [i], ptr, &ptr);
470 write_leb128 (jit->num_locals, ptr, &ptr);
471 for (i = 0; i < jit->num_locals; i++)
472 write_variable (&jit->locals [i], ptr, &ptr);
474 *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
475 if (jit->gsharedvt_info_var) {
476 write_variable (jit->gsharedvt_info_var, ptr, &ptr);
477 write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
481 g_assert (size < max_size);
482 total_size = size + sizeof (MonoDebugMethodAddress);
484 if (method_is_dynamic (method)) {
485 address = (MonoDebugMethodAddress *)g_malloc0 (total_size);
487 address = (MonoDebugMethodAddress *)mono_mempool_alloc (table->mp, total_size);
490 address->code_start = jit->code_start;
491 address->code_size = jit->code_size;
493 memcpy (&address->data, oldptr, size);
494 if (max_size > BUFSIZ)
497 g_hash_table_insert (table->method_address_hash, method, address);
499 mono_debugger_unlock ();
504 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
506 MonoDebugDataTable *table;
507 MonoDebugMethodAddress *address;
509 if (!mono_debug_initialized)
512 g_assert (method_is_dynamic (method));
514 mono_debugger_lock ();
516 table = lookup_data_table (domain);
518 address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
522 g_hash_table_remove (table->method_address_hash, method);
524 mono_debugger_unlock ();
528 mono_debug_add_delegate_trampoline (gpointer code, int size)
532 static inline guint32
533 read_leb128 (guint8 *ptr, guint8 **rptr)
535 guint32 result = 0, shift = 0;
538 guint8 byte = *ptr++;
540 result |= (byte & 0x7f) << shift;
541 if ((byte & 0x80) == 0)
551 read_sleb128 (guint8 *ptr, guint8 **rptr)
557 guint8 byte = *ptr++;
559 result |= (byte & 0x7f) << shift;
565 if ((shift < 32) && (byte & 0x40))
566 result |= - (1 << shift);
575 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
577 var->index = read_leb128 (ptr, &ptr);
578 var->offset = read_sleb128 (ptr, &ptr);
579 var->size = read_leb128 (ptr, &ptr);
580 var->begin_scope = read_leb128 (ptr, &ptr);
581 var->end_scope = read_leb128 (ptr, &ptr);
582 READ_UNALIGNED (MonoType *, ptr, var->type);
583 ptr += sizeof (gpointer);
588 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
592 g_free (jit->line_numbers);
593 g_free (jit->this_var);
594 g_free (jit->params);
595 g_free (jit->locals);
596 g_free (jit->gsharedvt_info_var);
597 g_free (jit->gsharedvt_locals_var);
601 static MonoDebugMethodJitInfo *
602 mono_debug_read_method (MonoDebugMethodAddress *address)
604 MonoDebugMethodJitInfo *jit;
608 jit = g_new0 (MonoDebugMethodJitInfo, 1);
609 jit->code_start = address->code_start;
610 jit->code_size = address->code_size;
612 ptr = (guint8 *) &address->data;
614 jit->prologue_end = read_leb128 (ptr, &ptr);
615 jit->epilogue_begin = read_leb128 (ptr, &ptr);
617 jit->num_line_numbers = read_leb128 (ptr, &ptr);
618 jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
619 for (i = 0; i < jit->num_line_numbers; i++) {
620 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
622 lne->il_offset = read_sleb128 (ptr, &ptr);
623 lne->native_offset = read_sleb128 (ptr, &ptr);
627 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
628 read_variable (jit->this_var, ptr, &ptr);
631 jit->num_params = read_leb128 (ptr, &ptr);
632 jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
633 for (i = 0; i < jit->num_params; i++)
634 read_variable (&jit->params [i], ptr, &ptr);
636 jit->num_locals = read_leb128 (ptr, &ptr);
637 jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
638 for (i = 0; i < jit->num_locals; i++)
639 read_variable (&jit->locals [i], ptr, &ptr);
642 jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
643 jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
644 read_variable (jit->gsharedvt_info_var, ptr, &ptr);
645 read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
651 static MonoDebugMethodJitInfo *
652 find_method (MonoMethod *method, MonoDomain *domain)
654 MonoDebugDataTable *table;
655 MonoDebugMethodAddress *address;
657 table = lookup_data_table (domain);
658 address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
663 return mono_debug_read_method (address);
666 MonoDebugMethodJitInfo *
667 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
669 MonoDebugMethodJitInfo *res;
671 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
674 mono_debugger_lock ();
675 res = find_method (method, domain);
676 mono_debugger_unlock ();
680 MonoDebugMethodAddressList *
681 mono_debug_lookup_method_addresses (MonoMethod *method)
683 g_assert_not_reached ();
688 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
690 MonoDebugMethodJitInfo *jit;
693 jit = find_method (method, domain);
694 if (!jit || !jit->line_numbers)
695 goto cleanup_and_fail;
697 for (i = jit->num_line_numbers - 1; i >= 0; i--) {
698 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
700 if (lne.native_offset <= native_offset) {
701 mono_debug_free_method_jit_info (jit);
702 return lne.il_offset;
707 mono_debug_free_method_jit_info (jit);
712 * mono_debug_il_offset_from_address:
714 * Compute the IL offset corresponding to NATIVE_OFFSET inside the native
715 * code of METHOD in DOMAIN.
718 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
722 mono_debugger_lock ();
724 res = il_offset_from_address (method, domain, native_offset);
726 mono_debugger_unlock ();
732 * mono_debug_lookup_source_location:
733 * @address: Native offset within the @method's machine code.
735 * Lookup the source code corresponding to the machine instruction located at
736 * native offset @address within @method.
738 * The returned `MonoDebugSourceLocation' contains both file / line number
739 * information and the corresponding IL offset. It must be freed by
740 * mono_debug_free_source_location().
742 MonoDebugSourceLocation *
743 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
745 MonoDebugMethodInfo *minfo;
746 MonoDebugSourceLocation *location;
749 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
752 mono_debugger_lock ();
753 minfo = mono_debug_lookup_method_internal (method);
754 if (!minfo || !minfo->handle) {
755 mono_debugger_unlock ();
759 if (!minfo->handle->ppdb && (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))) {
760 mono_debugger_unlock ();
764 offset = il_offset_from_address (method, domain, address);
766 mono_debugger_unlock ();
770 if (minfo->handle->ppdb)
771 location = mono_ppdb_lookup_location (minfo, offset);
773 location = mono_debug_symfile_lookup_location (minfo, offset);
774 mono_debugger_unlock ();
778 MonoDebugSourceLocation *
779 mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset)
781 MonoDebugSourceLocation *location;
783 mono_debugger_lock ();
784 if (minfo->handle->ppdb)
785 location = mono_ppdb_lookup_location (minfo, il_offset);
787 location = mono_debug_symfile_lookup_location (minfo, il_offset);
788 mono_debugger_unlock ();
793 * mono_debug_lookup_locals:
795 * Return information about the local variables of MINFO.
796 * The result should be freed using mono_debug_free_locals ().
799 mono_debug_lookup_locals (MonoMethod *method)
801 MonoDebugMethodInfo *minfo;
802 MonoDebugLocalsInfo *res;
804 if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
807 mono_debugger_lock ();
808 minfo = mono_debug_lookup_method_internal (method);
809 if (!minfo || !minfo->handle) {
810 mono_debugger_unlock ();
814 if (minfo->handle->ppdb) {
815 res = mono_ppdb_lookup_locals (minfo);
817 if (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))
820 res = mono_debug_symfile_lookup_locals (minfo);
822 mono_debugger_unlock ();
828 * mono_debug_free_locals:
830 * Free all the data allocated by mono_debug_lookup_locals ().
833 mono_debug_free_locals (MonoDebugLocalsInfo *info)
837 for (i = 0; i < info->num_locals; ++i)
838 g_free (info->locals [i].name);
839 g_free (info->locals);
840 g_free (info->code_blocks);
845 * mono_debug_free_source_location:
846 * @location: A `MonoDebugSourceLocation'.
848 * Frees the @location.
851 mono_debug_free_source_location (MonoDebugSourceLocation *location)
854 g_free (location->source_file);
860 * mono_debug_print_stack_frame:
861 * @native_offset: Native offset within the @method's machine code.
863 * Conventient wrapper around mono_debug_lookup_source_location() which can be
864 * used if you only want to use the location to print a stack frame.
867 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
869 MonoDebugSourceLocation *location;
870 gchar *fname, *ptr, *res;
873 fname = mono_method_full_name (method, TRUE);
874 for (ptr = fname; *ptr; ptr++) {
875 if (*ptr == ':') *ptr = '.';
878 location = mono_debug_lookup_source_location (method, native_offset, domain);
881 if (mono_debug_initialized) {
882 mono_debugger_lock ();
883 offset = il_offset_from_address (method, domain, native_offset);
884 mono_debugger_unlock ();
890 res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
892 res = g_strdup_printf ("at %s <IL 0x%05x, 0x%05x>", fname, offset, native_offset);
897 res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
898 location->source_file, location->row);
901 mono_debug_free_source_location (location);
906 mono_set_is_debugger_attached (gboolean attached)
908 is_attached = attached;
912 mono_is_debugger_attached (void)
921 typedef struct _BundledSymfile BundledSymfile;
923 struct _BundledSymfile {
924 BundledSymfile *next;
926 const mono_byte *raw_contents;
930 static BundledSymfile *bundled_symfiles = NULL;
933 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
935 BundledSymfile *bsymfile;
937 bsymfile = g_new0 (BundledSymfile, 1);
938 bsymfile->aname = assembly_name;
939 bsymfile->raw_contents = raw_contents;
940 bsymfile->size = size;
941 bsymfile->next = bundled_symfiles;
942 bundled_symfiles = bsymfile;
945 static MonoDebugHandle *
946 open_symfile_from_bundle (MonoImage *image)
948 BundledSymfile *bsymfile;
950 for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
951 if (strcmp (bsymfile->aname, image->module_name))
954 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
961 mono_debugger_lock (void)
963 g_assert (mono_debug_initialized);
964 mono_os_mutex_lock (&debugger_lock_mutex);
968 mono_debugger_unlock (void)
970 g_assert (mono_debug_initialized);
971 mono_os_mutex_unlock (&debugger_lock_mutex);
975 * mono_debug_enabled:
977 * Returns true is debug information is enabled. This doesn't relate if a debugger is present or not.
980 mono_debug_enabled (void)
982 return mono_debug_format != MONO_DEBUG_FORMAT_NONE;
986 mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
988 if (minfo->handle->ppdb)
989 mono_ppdb_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);
991 mono_debug_symfile_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);