5 #include <mono/metadata/class.h>
6 #include <mono/metadata/tabledefs.h>
7 #include <mono/metadata/tokentype.h>
8 #include <mono/metadata/debug-mono-symfile.h>
9 #include <mono/jit/codegen.h>
10 #include <mono/jit/debug.h>
12 #include "debug-private.h"
14 static MonoDebugHandle *mono_debug_handles = NULL;
15 static MonoDebugHandle *mono_default_debug_handle = NULL;
18 free_method_info (DebugMethodInfo *minfo)
20 if (minfo->line_numbers)
21 g_ptr_array_free (minfo->line_numbers, TRUE);
22 g_free (minfo->method_info.params);
23 g_free (minfo->method_info.locals);
27 static MonoDebugMethodInfo *
28 method_info_func (MonoSymbolFile *symfile, MonoMethod *method, gpointer user_data)
30 AssemblyDebugInfo *info = user_data;
31 DebugMethodInfo *minfo;
33 return (MonoDebugMethodInfo *) g_hash_table_lookup (info->handle->methods, method);
37 debug_arg_warning (const char *message)
39 g_warning ("Error while processing --debug-args arguments: %s", message);
43 mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **args)
45 MonoDebugHandle *debug;
48 debug = g_new0 (MonoDebugHandle, 1);
49 debug->name = g_strdup (assembly->image->name);
50 debug->format = format;
51 debug->producer_name = g_strdup_printf ("Mono JIT compiler version %s", VERSION);
52 debug->next_idx = 100;
55 debug->type_hash = g_hash_table_new (NULL, NULL);
56 debug->methods = g_hash_table_new_full (g_direct_hash, g_direct_equal,
57 NULL, (GDestroyNotify) free_method_info);
58 debug->source_files = g_ptr_array_new ();
60 for (ptr = args; ptr && *ptr; ptr++) {
61 const char *arg = *ptr;
64 switch (debug->format) {
65 case MONO_DEBUG_FORMAT_STABS:
66 case MONO_DEBUG_FORMAT_DWARF2:
67 if (!strncmp (arg, "filename=", 9)) {
69 debug_arg_warning ("The `filename' argument can be given only once.");
70 debug->filename = g_strdup (arg + 9);
72 } else if (!strncmp (arg, "objfile=", 8)) {
74 debug_arg_warning ("The `objfile' argument can be given only once.");
75 debug->objfile = g_strdup (arg + 8);
79 case MONO_DEBUG_FORMAT_DWARF2_PLUS:
80 if (!strcmp (arg, "dont_fallback")) {
81 debug->flags |= MONO_DEBUG_FLAGS_DONT_FALLBACK;
83 } else if (!strcmp (arg, "dont_precompile")) {
84 debug->flags |= MONO_DEBUG_FLAGS_DONT_PRECOMPILE;
87 debug->flags |= MONO_DEBUG_FLAGS_DONT_UPDATE_IL_FILES |
88 MONO_DEBUG_FLAGS_DONT_CREATE_IL_FILES;
90 case MONO_DEBUG_FORMAT_MONO:
91 debug->flags |= MONO_DEBUG_FLAGS_DONT_UPDATE_IL_FILES |
92 MONO_DEBUG_FLAGS_DONT_CREATE_IL_FILES;
98 if (debug->format != MONO_DEBUG_FORMAT_MONO) {
99 if (!strcmp (arg, "dont_assemble")) {
100 debug->flags |= MONO_DEBUG_FLAGS_DONT_ASSEMBLE;
102 } else if (!strcmp (arg, "update_on_exit")) {
103 debug->flags |= MONO_DEBUG_FLAGS_UPDATE_ON_EXIT;
105 } else if (!strcmp (arg, "install_il_files")) {
106 debug->flags |= MONO_DEBUG_FLAGS_INSTALL_IL_FILES;
108 } else if (!strcmp (arg, "dont_update_il_files")) {
109 debug->flags |= MONO_DEBUG_FLAGS_DONT_UPDATE_IL_FILES;
111 } else if (!strcmp (arg, "dont_create_il_files")) {
112 debug->flags |= MONO_DEBUG_FLAGS_DONT_CREATE_IL_FILES;
117 message = g_strdup_printf ("Unknown argument `%s'.", arg);
118 debug_arg_warning (message);
122 switch (debug->format) {
123 case MONO_DEBUG_FORMAT_STABS:
124 if (!debug->filename)
125 debug->filename = g_strdup_printf ("%s-stabs.s", g_basename (debug->name));
127 debug->objfile = g_strdup_printf ("%s.o", g_basename (debug->name));
129 case MONO_DEBUG_FORMAT_DWARF2:
130 if (!debug->filename)
131 debug->filename = g_strdup_printf ("%s-dwarf.s", g_basename (debug->name));
133 debug->objfile = g_strdup_printf ("%s.o", g_basename (debug->name));
135 case MONO_DEBUG_FORMAT_DWARF2_PLUS:
136 if (!mono_default_debug_handle && !(debug->flags & MONO_DEBUG_FLAGS_DONT_FALLBACK))
137 mono_debug_open (assembly, MONO_DEBUG_FORMAT_DWARF2, NULL);
139 case MONO_DEBUG_FORMAT_MONO:
140 if (!debug->filename)
141 debug->filename = g_strdup_printf ("%s.dbg", g_basename (debug->name));
144 g_assert_not_reached ();
147 debug->next = mono_debug_handles;
148 mono_debug_handles = debug;
150 if (!mono_default_debug_handle && (debug->format != MONO_DEBUG_FORMAT_DWARF2_PLUS))
151 mono_default_debug_handle = debug;
157 debug_load_method_lines (AssemblyDebugInfo* info)
164 if (!(info->handle->flags & MONO_DEBUG_FLAGS_DONT_UPDATE_IL_FILES)) {
165 char *command = g_strdup_printf ("monodis --output=%s %s",
166 info->ilfile, info->image->name);
167 struct stat stata, statb;
168 int need_update = FALSE;
170 if (stat (info->image->name, &stata)) {
171 g_warning ("cannot access assembly file (%s): %s",
172 info->image->name, g_strerror (errno));
177 /* If the stat() failed or the file is older. */
178 if (stat (info->ilfile, &statb)) {
179 /* Don't create any new *.il files if the user told us not to do so. */
180 if (!(info->handle->flags & MONO_DEBUG_FLAGS_DONT_CREATE_IL_FILES))
182 } else if (statb.st_mtime < stata.st_mtime)
186 g_print ("Recreating %s from %s.\n", info->ilfile, info->image->name);
187 if (system (command)) {
188 g_warning ("cannot create IL assembly file (%s): %s",
189 command, g_strerror (errno));
196 /* use an env var with directories for searching. */
197 if (!(f = fopen (info->ilfile, "r"))) {
198 g_warning ("cannot open IL assembly file %s", info->ilfile);
202 info->total_lines = 100;
203 info->moffsets = g_malloc (info->total_lines * sizeof (int));
206 while (fgets (buf, sizeof (buf), f)) {
209 info->moffsets [i++] = offset;
210 if (i + 2 >= info->total_lines) {
211 info->total_lines += 100;
212 info->moffsets = g_realloc (info->moffsets, info->total_lines * sizeof (int));
213 g_assert (info->moffsets);
216 if (!sscanf (buf, " // method line %d", &mnum))
221 if (mnum >= info->nmethods)
224 while (fgets (buf, sizeof (buf), f)) {
228 if (i + 2 >= info->total_lines) {
229 info->total_lines += 100;
230 info->moffsets = g_realloc (info->moffsets, info->total_lines * sizeof (int));
231 g_assert (info->moffsets);
234 if (strstr (buf, "}")) {
239 if (sscanf (buf, " IL_%x:", &newoffset)) {
245 info->moffsets [i] = offset;
247 /* g_print ("method %d found at %d\n", mnum, pos); */
248 info->mlines [mnum] = pos;
254 record_line_number (DebugMethodInfo *minfo, gpointer address, guint32 line, int is_basic_block)
256 DebugLineNumberInfo *lni = g_new0 (DebugLineNumberInfo, 1);
258 lni->address = address;
260 lni->is_basic_block = is_basic_block;
261 lni->source_file = minfo->source_file;
263 g_ptr_array_add (minfo->line_numbers, lni);
267 record_il_offset (GPtrArray *array, guint32 offset, guint32 address)
269 MonoDebugILOffsetInfo *info = g_new0 (MonoDebugILOffsetInfo, 1);
271 info->offset = offset;
272 info->address = address;
274 g_ptr_array_add (array, info);
278 debug_generate_method_lines (AssemblyDebugInfo *info, DebugMethodInfo *minfo, MonoFlowGraph* cfg)
280 guint32 st_address, st_line;
281 GPtrArray *il_offsets;
284 il_offsets = g_ptr_array_new ();
285 minfo->line_numbers = g_ptr_array_new ();
287 st_line = minfo->first_line;
288 st_address = minfo->method_info.prologue_end;
290 /* record_line_number takes absolute memory addresses. */
291 record_line_number (minfo, minfo->method_info.code_start, minfo->start_line, FALSE);
292 /* record_il_offsets uses offsets relative to minfo->method_info.code_start. */
293 record_il_offset (il_offsets, 0, st_address);
295 /* This is the first actual code line of the method. */
296 record_line_number (minfo, minfo->method_info.code_start + st_address, st_line, TRUE);
298 /* start lines of basic blocks */
299 for (i = 0; i < cfg->block_count; ++i) {
302 for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
303 MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
304 gint32 line_inc = 0, addr_inc;
307 st_line = minfo->first_line;
308 st_address = t->addr;
310 record_line_number (minfo, cfg->start + st_address, st_line, TRUE);
313 addr_inc = t->addr - st_address;
314 st_address += addr_inc;
316 if (t->cli_addr != -1)
317 record_il_offset (il_offsets, t->cli_addr, st_address);
323 if (t->cli_addr != -1) {
324 int *lines = info->moffsets + st_line;
327 while ((*k != -1) && (*k < t->cli_addr))
330 line_inc = k - lines;
335 record_line_number (minfo, minfo->method_info.code_start + st_address,
340 minfo->method_info.num_il_offsets = il_offsets->len;
341 minfo->method_info.il_offsets = g_new0 (MonoDebugILOffsetInfo, il_offsets->len);
342 for (i = 0; i < il_offsets->len; i++) {
343 MonoDebugILOffsetInfo *il = (MonoDebugILOffsetInfo *) g_ptr_array_index (il_offsets, i);
345 minfo->method_info.il_offsets [i] = *il;
348 g_ptr_array_free (il_offsets, TRUE);
351 static AssemblyDebugInfo *
352 mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
355 AssemblyDebugInfo *info;
357 if (debug->format == MONO_DEBUG_FORMAT_NONE)
360 for (tmp = debug->info; tmp; tmp = tmp->next) {
361 info = (AssemblyDebugInfo*)tmp->data;
363 if (info->image == image)
370 static AssemblyDebugInfo *
371 mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image)
373 AssemblyDebugInfo *info;
375 info = mono_debug_get_image (debug, image);
381 info = g_new0 (AssemblyDebugInfo, 1);
383 info->image->ref_count++;
384 info->name = g_strdup (image->assembly_name);
385 info->format = debug->format;
386 info->handle = debug;
388 info->source_file = debug->source_files->len;
389 g_ptr_array_add (debug->source_files, g_strdup_printf ("%s.il", image->assembly_name));
391 debug->info = g_list_prepend (debug->info, info);
393 info->nmethods = image->tables [MONO_TABLE_METHOD].rows + 1;
394 info->mlines = g_new0 (int, info->nmethods);
396 switch (info->format) {
397 case MONO_DEBUG_FORMAT_STABS:
398 case MONO_DEBUG_FORMAT_DWARF2:
399 if (debug->flags & MONO_DEBUG_FLAGS_INSTALL_IL_FILES) {
400 gchar *dirname = g_path_get_dirname (image->name);
401 info->ilfile = g_strdup_printf ("%s/%s.il", dirname, info->name);
404 info->ilfile = g_strdup_printf ("%s.il", info->name);
406 case MONO_DEBUG_FORMAT_DWARF2_PLUS: {
407 gchar *dirname = g_path_get_dirname (image->name);
408 info->filename = g_strdup_printf ("%s/%s-debug.s", dirname, info->name);
409 info->objfile = g_strdup_printf ("%s-debug.o", info->name);
410 mono_debug_open_assembly_dwarf2_plus (info);
415 case MONO_DEBUG_FORMAT_MONO:
416 info->filename = g_strdup_printf ("%s.dbg", info->name);
417 info->mono_symfile = mono_debug_open_mono_symbol_file (info->image, info->filename, TRUE);
424 if ((debug->format != MONO_DEBUG_FORMAT_DWARF2_PLUS) &&
425 (debug->format != MONO_DEBUG_FORMAT_MONO))
426 debug_load_method_lines (info);
432 mono_debug_add_image (MonoDebugHandle* debug, MonoImage *image)
434 mono_debug_open_image (debug, image);
438 mono_debug_write_symbols (MonoDebugHandle *debug)
442 if (!debug || !debug->dirty)
445 switch (debug->format) {
446 case MONO_DEBUG_FORMAT_STABS:
447 mono_debug_write_stabs (debug);
449 case MONO_DEBUG_FORMAT_DWARF2:
450 mono_debug_write_dwarf2 (debug);
452 case MONO_DEBUG_FORMAT_DWARF2_PLUS:
453 for (tmp = debug->info; tmp; tmp = tmp->next) {
454 AssemblyDebugInfo *info = (AssemblyDebugInfo*)tmp->data;
456 mono_debug_write_assembly_dwarf2_plus (info);
459 case MONO_DEBUG_FORMAT_MONO:
460 for (tmp = debug->info; tmp; tmp = tmp->next) {
461 AssemblyDebugInfo *info = (AssemblyDebugInfo*)tmp->data;
463 if (!info->mono_symfile)
466 mono_debug_update_mono_symbol_file (info->mono_symfile, method_info_func, info);
470 g_assert_not_reached ();
473 debug->dirty = FALSE;
477 mono_debug_make_symbols (void)
479 MonoDebugHandle *debug;
481 for (debug = mono_debug_handles; debug; debug = debug->next)
482 mono_debug_write_symbols (debug);
486 mono_debug_close_assembly (AssemblyDebugInfo* info)
488 switch (info->format) {
489 case MONO_DEBUG_FORMAT_DWARF2_PLUS:
490 mono_debug_close_assembly_dwarf2_plus (info);
492 case MONO_DEBUG_FORMAT_MONO:
493 if (info->mono_symfile != NULL)
494 mono_debug_close_mono_symbol_file (info->mono_symfile);
499 g_free (info->mlines);
500 g_free (info->moffsets);
502 g_free (info->ilfile);
503 g_free (info->filename);
504 g_free (info->objfile);
509 mono_debug_cleanup (void)
511 MonoDebugHandle *debug, *temp;
513 for (debug = mono_debug_handles; debug; debug = temp) {
516 if (debug->flags & MONO_DEBUG_FLAGS_UPDATE_ON_EXIT)
517 mono_debug_write_symbols (debug);
520 for (tmp = debug->info; tmp; tmp = tmp->next) {
521 AssemblyDebugInfo* info = (AssemblyDebugInfo*)tmp->data;
523 mono_debug_close_assembly (info);
526 g_ptr_array_free (debug->source_files, TRUE);
527 g_hash_table_destroy (debug->methods);
528 g_hash_table_destroy (debug->type_hash);
529 g_free (debug->producer_name);
530 g_free (debug->name);
536 mono_debug_handles = NULL;
537 mono_default_debug_handle = NULL;
541 mono_debug_get_type (MonoDebugHandle *debug, MonoClass *klass)
545 mono_class_init (klass);
547 index = GPOINTER_TO_INT (g_hash_table_lookup (debug->type_hash, klass));
553 index = ++debug->next_klass_idx;
554 g_hash_table_insert (debug->type_hash, klass, GINT_TO_POINTER (index));
559 switch (klass->byval_arg.type) {
560 case MONO_TYPE_CLASS:
562 mono_debug_get_type (debug, klass->parent);
564 for (i = 0; i < klass->method.count; i++) {
565 MonoMethod *method = klass->methods [i];
566 MonoType *ret_type = NULL;
569 if (method->signature->ret->type != MONO_TYPE_VOID)
570 ret_type = method->signature->ret;
573 MonoClass *ret_klass = mono_class_from_mono_type (ret_type);
574 mono_debug_get_type (debug, ret_klass);
577 for (j = 0; j < method->signature->param_count; j++) {
578 MonoType *sub_type = method->signature->params [j];
579 MonoClass *sub_klass = mono_class_from_mono_type (sub_type);
580 mono_debug_get_type (debug, sub_klass);
584 case MONO_TYPE_VALUETYPE:
585 for (i = 0; i < klass->field.count; i++) {
586 MonoClass *subclass = mono_class_from_mono_type (klass->fields [i].type);
587 mono_debug_get_type (debug, subclass);
590 case MONO_TYPE_ARRAY:
591 case MONO_TYPE_SZARRAY:
592 mono_debug_get_type (debug, klass->element_class);
602 mono_debug_handle_from_class (MonoClass *klass)
604 MonoDebugHandle *debug;
606 mono_class_init (klass);
608 for (debug = mono_debug_handles; debug; debug = debug->next) {
611 for (tmp = debug->info; tmp; tmp = tmp->next) {
612 AssemblyDebugInfo *info = (AssemblyDebugInfo*)tmp->data;
614 if (info->image == klass->image)
623 il_offset_from_address (DebugMethodInfo *minfo, guint32 address)
627 for (i = 0; i < minfo->method_info.num_il_offsets; i++) {
628 MonoDebugILOffsetInfo *ilo = &minfo->method_info.il_offsets [i];
630 if (ilo->address > address)
638 address_from_il_offset (DebugMethodInfo *minfo, guint32 il_offset)
642 for (i = 0; i < minfo->method_info.num_il_offsets; i++) {
643 MonoDebugILOffsetInfo *ilo = &minfo->method_info.il_offsets [i];
645 if (ilo->offset > il_offset)
653 mono_debug_add_type (MonoClass *klass)
655 MonoDebugHandle *debug = mono_debug_handle_from_class (klass);
657 g_assert (debug != NULL);
659 mono_debug_get_type (debug, klass);
663 il_offset_from_position (MonoFlowGraph *cfg, MonoPosition *pos)
668 if (pos->abs_pos == 0)
671 if (pos->pos.bid >= cfg->block_count)
674 bblock = &cfg->bblocks [pos->pos.bid];
675 if (pos->pos.tid >= bblock->forest->len)
678 tree = (MBTree *) g_ptr_array_index (bblock->forest, pos->pos.tid);
680 return tree->cli_addr;
684 mono_debug_add_method (MonoFlowGraph *cfg)
686 MonoMethod *method = cfg->method;
687 MonoClass *klass = method->klass;
688 int method_number = 0, line = 0, start_line = 0, end_line = 0, i;
689 MonoDebugHandle* debug;
690 AssemblyDebugInfo* info;
691 DebugMethodInfo *minfo;
694 mono_class_init (klass);
696 debug = mono_debug_handle_from_class (klass);
698 if (mono_default_debug_handle)
699 debug = mono_default_debug_handle;
704 info = mono_debug_open_image (debug, klass->image);
707 * Find the method index in the image.
709 for (i = 0; klass->methods && i < klass->method.count; ++i) {
710 if (klass->methods [i] == method) {
711 method_number = klass->method.first + i + 1;
712 line = info->mlines [method_number];
717 if (g_hash_table_lookup (debug->methods, method))
722 if (info->moffsets) {
723 /* info->moffsets contains -1 "outside" of functions. */
724 for (i = line; (i > 0) && (info->moffsets [i] == 0); i--)
728 for (i = start_line; info->moffsets [i] != -1; i++)
733 name = g_strdup_printf ("%s%s%s.%s", klass->name_space, klass->name_space [0]? ".": "",
734 klass->name, method->name);
736 minfo = g_new0 (DebugMethodInfo, 1);
738 minfo->start_line = start_line;
739 minfo->first_line = line;
740 minfo->last_line = end_line;
741 minfo->source_file = info->source_file;
743 minfo->method_info.code_start = cfg->start;
744 minfo->method_info.code_size = cfg->epilogue_end;
745 minfo->method_number = method_number;
746 minfo->method_info.method = method;
747 minfo->method_info.num_params = method->signature->param_count;
748 minfo->method_info.params = g_new0 (MonoDebugVarInfo, minfo->method_info.num_params);
749 minfo->method_info.prologue_end = cfg->prologue_end;
750 minfo->method_info.epilogue_begin = cfg->epilog;
752 if (method->signature->hasthis) {
753 MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index;
755 minfo->method_info.this_var = g_new0 (MonoDebugVarInfo, 1);
756 minfo->method_info.this_var->offset = ptr->offset;
759 for (i = 0; i < minfo->method_info.num_params; i++) {
760 MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index +
761 method->signature->hasthis;
763 minfo->method_info.params [i].offset = ptr [i].offset;
766 debug_generate_method_lines (info, minfo, cfg);
768 if (!method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
769 MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
770 MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->locals_start_index;
771 MonoDebugVarInfo *locals;
773 locals = g_new0 (MonoDebugVarInfo, header->num_locals);
774 for (i = 0; i < header->num_locals; i++) {
775 gint32 begin_offset, end_offset;
776 gint32 begin_scope, end_scope;
778 if (ptr [i].reg >= 0) {
779 locals [i].index = ptr [i].reg | MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER;
780 locals [i].offset = 0;
782 locals [i].offset = ptr [i].offset;
784 begin_offset = il_offset_from_position (cfg, &ptr [i].range.first_use);
785 end_offset = il_offset_from_position (cfg, &ptr [i].range.last_use);
789 begin_scope = address_from_il_offset (minfo, begin_offset);
790 end_scope = address_from_il_offset (minfo, end_offset);
793 locals [i].begin_scope = begin_scope;
795 locals [i].begin_scope = minfo->method_info.prologue_end;
797 locals [i].end_scope = end_scope;
799 locals [i].end_scope = minfo->method_info.epilogue_begin;
802 minfo->method_info.num_locals = header->num_locals;
803 minfo->method_info.locals = locals;
806 g_hash_table_insert (debug->methods, method, minfo);
810 mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number)
812 MonoDebugHandle *debug;
813 DebugMethodInfo *minfo = NULL;
816 for (debug = mono_debug_handles; debug; debug = debug->next) {
817 minfo = g_hash_table_lookup (debug->methods, method);
826 if (minfo->info->mono_symfile) {
827 gint32 offset = il_offset_from_address (minfo, address);
832 return mono_debug_find_source_location (minfo->info->mono_symfile, method, offset, line_number);
835 if (!minfo->line_numbers)
838 for (i = 0; i < minfo->line_numbers->len; i++) {
839 DebugLineNumberInfo *lni = g_ptr_array_index (minfo->line_numbers, i);
841 if ((gchar *)lni->address > minfo->method_info.code_start + address) {
842 gchar *source_file = g_ptr_array_index (debug->source_files, lni->source_file);
845 *line_number = lni->line;
846 return g_strdup (source_file);
848 return g_strdup_printf ("%s:%d", source_file, lni->line);
856 mono_debug_il_offset_from_address (MonoMethod *method, gint32 address)
858 MonoDebugHandle *debug;
859 DebugMethodInfo *minfo = NULL;
864 for (debug = mono_debug_handles; debug; debug = debug->next) {
865 minfo = g_hash_table_lookup (debug->methods, method);
871 if (!minfo || !minfo->method_info.il_offsets)
874 return il_offset_from_address (minfo, address);
878 mono_debug_address_from_il_offset (MonoMethod *method, gint32 il_offset)
880 MonoDebugHandle *debug;
881 DebugMethodInfo *minfo = NULL;
886 for (debug = mono_debug_handles; debug; debug = debug->next) {
887 minfo = g_hash_table_lookup (debug->methods, method);
893 if (!minfo || !minfo->method_info.il_offsets)
896 return address_from_il_offset (minfo, il_offset);