4 #include <mono/metadata/assembly.h>
5 #include <mono/metadata/metadata.h>
6 #include <mono/metadata/tabledefs.h>
7 #include <mono/metadata/tokentype.h>
8 #include <mono/metadata/appdomain.h>
9 #include <mono/metadata/gc-internal.h>
10 #include <mono/os/gc_wrapper.h>
11 #include <mono/metadata/object-internals.h>
12 #include <mono/metadata/class-internals.h>
13 #include <mono/metadata/exception.h>
14 #include <mono/metadata/mono-debug.h>
15 #include <mono/metadata/mono-debug-debugger.h>
16 #include <mono/metadata/mono-endian.h>
18 #define SYMFILE_TABLE_CHUNK_SIZE 16
19 #define RANGE_TABLE_CHUNK_SIZE 256
20 #define CLASS_TABLE_CHUNK_SIZE 256
21 #define TYPE_TABLE_PTR_CHUNK_SIZE 256
22 #define TYPE_TABLE_CHUNK_SIZE 65536
23 #define MISC_TABLE_PTR_CHUNK_SIZE 256
24 #define MISC_TABLE_CHUNK_SIZE 65536
26 static guint32 debugger_lock_level = 0;
27 static CRITICAL_SECTION debugger_lock_mutex;
28 static gboolean mono_debugger_initialized = FALSE;
29 static MonoObject *last_exception = NULL;
31 static gboolean must_reload_symtabs = FALSE;
32 static gboolean builtin_types_initialized = FALSE;
34 static GHashTable *images = NULL;
35 static GHashTable *type_table = NULL;
36 static GHashTable *misc_table = NULL;
37 static GHashTable *class_table = NULL;
38 static GHashTable *class_info_table = NULL;
40 static MonoDebuggerRangeInfo *allocate_range_entry (MonoDebuggerSymbolFile *symfile);
41 static MonoDebuggerClassInfo *allocate_class_entry (MonoDebuggerSymbolFile *symfile);
42 static guint32 allocate_type_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr);
43 static guint32 write_type (MonoDebuggerSymbolTable *table, MonoType *type);
44 static guint32 do_write_class (MonoDebuggerSymbolTable *table, MonoClass *klass,
45 MonoDebuggerClassInfo *cinfo);
46 static guint32 write_class (MonoDebuggerSymbolTable *table, MonoClass *klass);
48 MonoDebuggerSymbolTable *mono_debugger_symbol_table = NULL;
49 void (*mono_debugger_event_handler) (MonoDebuggerEvent event, gpointer data, guint32 arg) = NULL;
51 #define WRITE_UINT32(ptr,value) G_STMT_START { \
52 * ((guint32 *) ptr) = value; \
56 #define WRITE_POINTER(ptr,value) G_STMT_START { \
57 * ((gpointer *) ptr) = value; \
58 ptr += sizeof (gpointer); \
61 #define WRITE_STRING(ptr,value) G_STMT_START { \
62 memcpy (ptr, value, strlen (value)+1); \
63 ptr += strlen (value)+1; \
67 gpointer stack_pointer;
68 MonoObject *exception_obj;
69 } MonoDebuggerExceptionInfo;
71 #ifndef PLATFORM_WIN32
73 MonoDebuggerIOLayer mono_debugger_io_layer = {
74 InitializeCriticalSection, DeleteCriticalSection, TryEnterCriticalSection,
75 EnterCriticalSection, LeaveCriticalSection, WaitForSingleObjectEx, SignalObjectAndWait,
76 WaitForMultipleObjectsEx, CreateSemaphore, ReleaseSemaphore, CreateThread,
83 mono_debugger_lock (void)
85 if (!mono_debugger_initialized) {
86 debugger_lock_level++;
90 EnterCriticalSection (&debugger_lock_mutex);
91 debugger_lock_level++;
95 mono_debugger_unlock (void)
97 g_assert (debugger_lock_level > 0);
99 if (!mono_debugger_initialized) {
100 debugger_lock_level--;
104 if (debugger_lock_level == 1) {
105 if (must_reload_symtabs) {
106 mono_debugger_event (MONO_DEBUGGER_EVENT_RELOAD_SYMTABS, NULL, 0);
107 must_reload_symtabs = FALSE;
111 debugger_lock_level--;
112 LeaveCriticalSection (&debugger_lock_mutex);
115 static MonoDebuggerSymbolFile *
116 allocate_symbol_file_entry (MonoDebuggerSymbolTable *table)
118 MonoDebuggerSymbolFile *symfile;
120 if (!table->symbol_files)
121 table->symbol_files = g_new0 (MonoDebuggerSymbolFile *, SYMFILE_TABLE_CHUNK_SIZE);
122 else if (!((table->num_symbol_files + 1) % SYMFILE_TABLE_CHUNK_SIZE)) {
123 guint32 chunks = (table->num_symbol_files + 1) / SYMFILE_TABLE_CHUNK_SIZE;
124 guint32 size = sizeof (MonoDebuggerSymbolFile *) * SYMFILE_TABLE_CHUNK_SIZE * (chunks + 1);
126 table->symbol_files = g_realloc (table->symbol_files, size);
129 symfile = g_new0 (MonoDebuggerSymbolFile, 1);
130 symfile->index = table->num_symbol_files;
131 symfile->range_entry_size = sizeof (MonoDebuggerRangeInfo);
132 symfile->class_entry_size = sizeof (MonoDebuggerClassInfo);
133 symfile->class_table_size = sizeof (MonoDebuggerClassTable);
134 table->symbol_files [table->num_symbol_files++] = symfile;
139 mono_debugger_initialize (void)
141 MonoDebuggerSymbolTable *symbol_table;
143 MONO_GC_REGISTER_ROOT (last_exception);
145 g_assert (!mono_debugger_initialized);
147 InitializeCriticalSection (&debugger_lock_mutex);
148 mono_debugger_initialized = TRUE;
150 mono_debugger_lock ();
152 symbol_table = g_new0 (MonoDebuggerSymbolTable, 1);
153 symbol_table->magic = MONO_DEBUGGER_MAGIC;
154 symbol_table->version = MONO_DEBUGGER_VERSION;
155 symbol_table->total_size = sizeof (MonoDebuggerSymbolTable);
157 images = g_hash_table_new (g_direct_hash, g_direct_equal);
158 type_table = g_hash_table_new (g_direct_hash, g_direct_equal);
159 misc_table = g_hash_table_new (g_direct_hash, g_direct_equal);
160 class_table = g_hash_table_new (g_direct_hash, g_direct_equal);
161 class_info_table = g_hash_table_new (g_direct_hash, g_direct_equal);
163 mono_debugger_symbol_table = symbol_table;
165 mono_debugger_unlock ();
168 MonoDebuggerSymbolFile *
169 mono_debugger_add_symbol_file (MonoDebugHandle *handle)
171 MonoDebuggerSymbolFile *info;
173 g_assert (mono_debugger_initialized);
174 mono_debugger_lock ();
176 info = g_hash_table_lookup (images, handle->image);
178 mono_debugger_unlock ();
182 info = allocate_symbol_file_entry (mono_debugger_symbol_table);
183 info->symfile = handle->symfile;
184 info->image = handle->image;
185 info->image_file = handle->image_file;
187 g_hash_table_insert (images, handle->image, info);
188 mono_debugger_unlock ();
194 write_builtin_type (MonoDebuggerSymbolTable *table, MonoDebuggerSymbolFile *symfile,
195 MonoClass *klass, MonoDebuggerBuiltinTypeInfo *info)
197 guint8 buffer [BUFSIZ], *ptr = buffer;
200 g_assert (!klass->init_pending);
201 mono_class_init (klass);
203 switch (klass->byval_arg.type) {
205 *ptr++ = MONO_DEBUGGER_TYPE_KIND_UNKNOWN;
206 WRITE_UINT32 (ptr, 0);
210 case MONO_TYPE_BOOLEAN:
222 *ptr++ = MONO_DEBUGGER_TYPE_KIND_FUNDAMENTAL;
223 WRITE_UINT32 (ptr, klass->instance_size - sizeof (MonoObject));
227 case MONO_TYPE_STRING: {
230 *ptr++ = MONO_DEBUGGER_TYPE_KIND_STRING;
231 WRITE_UINT32 (ptr, klass->instance_size);
233 *ptr++ = (guint8*)&string.length - (guint8*)&string;
234 *ptr++ = sizeof (string.length);
235 *ptr++ = (guint8*)&string.chars - (guint8*)&string;
242 *ptr++ = MONO_DEBUGGER_TYPE_KIND_FUNDAMENTAL;
243 WRITE_UINT32 (ptr, sizeof (void *));
247 case MONO_TYPE_VALUETYPE:
248 *ptr++ = MONO_DEBUGGER_TYPE_KIND_STRUCT;
249 WRITE_UINT32 (ptr, klass->instance_size);
253 case MONO_TYPE_CLASS:
254 *ptr++ = MONO_DEBUGGER_TYPE_KIND_CLASS;
255 WRITE_UINT32 (ptr, klass->instance_size);
259 case MONO_TYPE_OBJECT:
260 g_assert (klass == mono_defaults.object_class);
261 *ptr++ = MONO_DEBUGGER_TYPE_KIND_OBJECT;
262 WRITE_UINT32 (ptr, klass->instance_size);
267 g_error (G_STRLOC ": Unknown builtin type %s.%s - %d", klass->name_space, klass->name, klass->byval_arg.type);
271 info->type_info = allocate_type_entry (table, size, &info->type_data);
272 memcpy (info->type_data, buffer, size);
274 info->centry->info = g_new0 (MonoDebuggerClassInfo, 1); //allocate_class_entry (symfile);
275 info->centry->info->klass = klass;
277 info->centry->info->token = klass->element_class->type_token;
278 info->centry->info->rank = klass->rank;
280 info->centry->info->token = klass->type_token;
281 info->centry->info->type_info = info->type_info;
284 static MonoDebuggerBuiltinTypeInfo *
285 add_builtin_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
287 MonoDebuggerClassEntry *centry;
288 MonoDebuggerBuiltinTypeInfo *info;
290 centry = g_new0 (MonoDebuggerClassEntry, 1);
292 info = g_new0 (MonoDebuggerBuiltinTypeInfo, 1);
294 info->centry = centry;
296 g_hash_table_insert (class_info_table, klass, centry);
298 write_builtin_type (mono_debugger_symbol_table, symfile, klass, info);
303 add_builtin_type_2 (MonoDebuggerBuiltinTypeInfo *info)
305 info->class_info = do_write_class (mono_debugger_symbol_table, info->klass, NULL);
306 * (guint32 *) (info->type_data + 5) = info->class_info;
310 add_exception_class (MonoDebuggerSymbolFile *symfile, MonoException *exc)
312 mono_debugger_start_add_type (symfile, ((MonoObject *) exc)->vtable->klass);
313 mono_debugger_add_type (symfile, ((MonoObject *) exc)->vtable->klass);
316 MonoDebuggerBuiltinTypes *
317 mono_debugger_add_builtin_types (MonoDebuggerSymbolFile *symfile)
319 MonoDebuggerBuiltinTypes *types = g_new0 (MonoDebuggerBuiltinTypes, 1);
322 mono_debugger_symbol_table->corlib = symfile;
323 mono_debugger_symbol_table->builtin_types = types;
325 types->total_size = sizeof (MonoDebuggerBuiltinTypes);
326 types->type_info_size = sizeof (MonoDebuggerBuiltinTypeInfo);
328 types->object_type = add_builtin_type (symfile, mono_defaults.object_class);
329 klass = mono_class_from_name (mono_defaults.corlib, "System", "ValueType");
331 types->valuetype_type = add_builtin_type (symfile, klass);
333 types->byte_type = add_builtin_type (symfile, mono_defaults.byte_class);
334 types->void_type = add_builtin_type (symfile, mono_defaults.void_class);
335 types->boolean_type = add_builtin_type (symfile, mono_defaults.boolean_class);
336 types->sbyte_type = add_builtin_type (symfile, mono_defaults.sbyte_class);
337 types->int16_type = add_builtin_type (symfile, mono_defaults.int16_class);
338 types->uint16_type = add_builtin_type (symfile, mono_defaults.uint16_class);
339 types->int32_type = add_builtin_type (symfile, mono_defaults.int32_class);
340 types->uint32_type = add_builtin_type (symfile, mono_defaults.uint32_class);
341 types->int_type = add_builtin_type (symfile, mono_defaults.int_class);
342 types->uint_type = add_builtin_type (symfile, mono_defaults.uint_class);
343 types->int64_type = add_builtin_type (symfile, mono_defaults.int64_class);
344 types->uint64_type = add_builtin_type (symfile, mono_defaults.uint64_class);
345 types->single_type = add_builtin_type (symfile, mono_defaults.single_class);
346 types->double_type = add_builtin_type (symfile, mono_defaults.double_class);
347 types->char_type = add_builtin_type (symfile, mono_defaults.char_class);
348 types->string_type = add_builtin_type (symfile, mono_defaults.string_class);
350 klass = mono_class_from_name (mono_defaults.corlib, "System", "Type");
352 types->type_type = add_builtin_type (symfile, klass);
354 types->enum_type = add_builtin_type (symfile, mono_defaults.enum_class);
355 types->array_type = add_builtin_type (symfile, mono_defaults.array_class);
356 types->exception_type = add_builtin_type (symfile, mono_defaults.exception_class);
358 add_builtin_type_2 (types->object_type);
359 add_builtin_type_2 (types->valuetype_type);
361 add_builtin_type_2 (types->byte_type);
362 add_builtin_type_2 (types->void_type);
363 add_builtin_type_2 (types->boolean_type);
364 add_builtin_type_2 (types->sbyte_type);
365 add_builtin_type_2 (types->int16_type);
366 add_builtin_type_2 (types->uint16_type);
367 add_builtin_type_2 (types->int32_type);
368 add_builtin_type_2 (types->uint32_type);
369 add_builtin_type_2 (types->int_type);
370 add_builtin_type_2 (types->uint_type);
371 add_builtin_type_2 (types->int64_type);
372 add_builtin_type_2 (types->uint64_type);
373 add_builtin_type_2 (types->single_type);
374 add_builtin_type_2 (types->double_type);
375 add_builtin_type_2 (types->char_type);
376 add_builtin_type_2 (types->string_type);
377 add_builtin_type_2 (types->type_type);
379 add_builtin_type_2 (types->enum_type);
380 add_builtin_type_2 (types->array_type);
381 add_builtin_type_2 (types->exception_type);
383 add_exception_class (symfile, mono_get_exception_divide_by_zero ());
384 add_exception_class (symfile, mono_get_exception_security ());
385 add_exception_class (symfile, mono_get_exception_arithmetic ());
386 add_exception_class (symfile, mono_get_exception_overflow ());
387 add_exception_class (symfile, mono_get_exception_null_reference ());
388 add_exception_class (symfile, mono_get_exception_thread_abort ());
389 add_exception_class (symfile, mono_get_exception_invalid_cast ());
390 add_exception_class (symfile, mono_get_exception_index_out_of_range ());
391 add_exception_class (symfile, mono_get_exception_thread_abort ());
392 add_exception_class (symfile, mono_get_exception_index_out_of_range ());
393 add_exception_class (symfile, mono_get_exception_array_type_mismatch ());
394 add_exception_class (symfile, mono_get_exception_missing_method ());
395 add_exception_class (symfile, mono_get_exception_appdomain_unloaded ());
396 add_exception_class (symfile, mono_get_exception_stack_overflow ());
398 builtin_types_initialized = TRUE;
404 write_class (MonoDebuggerSymbolTable *table, MonoClass *klass)
406 MonoDebuggerClassEntry *centry;
408 if (builtin_types_initialized && !klass->init_pending)
409 mono_class_init (klass);
411 centry = g_hash_table_lookup (class_info_table, klass);
413 MonoDebuggerSymbolFile *symfile = _mono_debugger_get_symfile (klass->image);
416 mono_debugger_start_add_type (symfile, klass);
417 centry = g_hash_table_lookup (class_info_table, klass);
422 g_assert (centry->info->type_info);
423 return centry->info->type_info;
426 if (!centry->type_reference) {
429 centry->type_reference = allocate_type_entry (table, 5, &ptr);
431 *ptr++ = MONO_DEBUGGER_TYPE_KIND_REFERENCE;
432 WRITE_POINTER (ptr, klass);
435 return centry->type_reference;
439 mono_debugger_start_add_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
441 MonoDebuggerClassEntry *centry;
443 mono_debugger_lock ();
444 centry = g_hash_table_lookup (class_info_table, klass);
446 mono_debugger_unlock ();
450 centry = g_new0 (MonoDebuggerClassEntry, 1);
451 g_hash_table_insert (class_info_table, klass, centry);
452 mono_debugger_unlock ();
456 mono_debugger_add_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
458 MonoDebuggerClassEntry *centry;
460 mono_debugger_lock ();
461 centry = g_hash_table_lookup (class_info_table, klass);
465 mono_debugger_unlock ();
469 centry->info = allocate_class_entry (symfile);
470 centry->info->klass = klass;
472 centry->info->token = klass->element_class->type_token;
473 centry->info->rank = klass->rank;
475 centry->info->token = klass->type_token;
477 do_write_class (mono_debugger_symbol_table, klass, centry->info);
479 g_assert (centry->info && centry->info->type_info);
481 symfile->generation++;
482 must_reload_symtabs = TRUE;
484 mono_debugger_unlock ();
488 mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *minfo,
489 MonoDebugMethodJitInfo *jit)
491 MonoSymbolFileMethodAddress *address;
492 MonoSymbolFileLexicalBlockEntry *block;
493 MonoDebugVarInfo *var_table;
494 MonoDebuggerRangeInfo *range;
495 MonoMethodHeader *header;
496 guint32 size, num_variables, variable_size, variable_offset;
497 guint32 type_size, type_offset, *type_index_table, has_this;
498 guint32 line_size, line_offset, block_offset, block_size;
499 MonoDebugLexicalBlockEntry *block_table;
500 MonoDebugLineNumberEntry *line_table;
505 if (!symfile->symfile->method_hash)
508 header = ((MonoMethodNormal *) minfo->method)->header;
510 symfile->generation++;
512 size = sizeof (MonoSymbolFileMethodAddress);
514 num_variables = jit->num_params + read32(&(minfo->entry->_num_locals));
515 has_this = jit->this_var != NULL;
517 variable_size = (num_variables + has_this) * sizeof (MonoDebugVarInfo);
518 variable_offset = size;
519 size += variable_size;
521 type_size = (num_variables + 1) * sizeof (gpointer);
525 if (jit->line_numbers) {
527 line_size = jit->line_numbers->len * sizeof (MonoDebugLineNumberEntry);
531 block_size = read32(&(minfo->entry->_num_lexical_blocks)) * sizeof (MonoSymbolFileLexicalBlockEntry);
535 address = g_malloc0 (size);
536 ptr = (guint8 *) address;
538 block = (MonoSymbolFileLexicalBlockEntry *)
539 (symfile->symfile->raw_contents + read32(&(minfo->entry->_lexical_block_table_offset)));
540 block_table = (MonoDebugLexicalBlockEntry *) (ptr + block_offset);
542 for (i = 0; i < read32(&(minfo->entry->_num_lexical_blocks)); i++, block++) {
543 block_table [i].start_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_start_offset)));
544 block_table [i].end_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_end_offset)));
547 address->size = size;
548 address->has_this = has_this;
549 address->num_params = jit->num_params;
550 address->start_address = jit->code_start;
551 address->end_address = jit->code_start + jit->code_size;
552 address->method_start_address = address->start_address + jit->prologue_end;
553 address->method_end_address = address->start_address + jit->epilogue_begin;
554 address->wrapper_address = jit->wrapper_addr;
555 address->variable_table_offset = variable_offset;
556 address->type_table_offset = type_offset;
557 address->lexical_block_table_offset = block_offset;
559 if (jit->line_numbers) {
560 address->num_line_numbers = jit->line_numbers->len;
561 address->line_number_offset = line_offset;
563 line_table = (MonoDebugLineNumberEntry *) (ptr + line_offset);
564 memcpy (line_table, jit->line_numbers->data, line_size);
567 range = allocate_range_entry (symfile);
568 range->index = minfo->index;
569 range->start_address = address->start_address;
570 range->end_address = address->end_address;
571 range->dynamic_data = address;
572 range->dynamic_size = size;
574 if ((minfo->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
575 (minfo->method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
576 (minfo->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
579 var_table = (MonoDebugVarInfo *) (ptr + variable_offset);
580 type_table = (guint32 *) (ptr + type_offset);
582 type_index_table = (guint32 *)
583 (symfile->symfile->raw_contents + read32(&(minfo->entry->_type_index_table_offset)));
586 *var_table++ = *jit->this_var;
587 *type_table++ = write_type (mono_debugger_symbol_table, &minfo->method->klass->this_arg);
589 for (i = 0; i < jit->num_params; i++) {
590 *var_table++ = jit->params [i];
591 *type_table++ = write_type (mono_debugger_symbol_table, minfo->method->signature->params [i]);
594 if (jit->num_locals < read32(&(minfo->entry->_num_locals))) {
595 g_warning (G_STRLOC ": Method %s.%s has %d locals, but symbol file claims it has %d.",
596 minfo->method->klass->name, minfo->method->name, jit->num_locals,
597 read32(&(minfo->entry->_num_locals)));
598 var_table += read32(&(minfo->entry->_num_locals));
600 g_assert ((header != NULL) || (minfo->entry->_num_locals == 0));
601 for (i = 0; i < read32(&(minfo->entry->_num_locals)); i++) {
602 *var_table++ = jit->locals [i];
603 *type_table++ = write_type (mono_debugger_symbol_table, header->locals [i]);
607 must_reload_symtabs = TRUE;
610 static MonoDebuggerRangeInfo *
611 allocate_range_entry (MonoDebuggerSymbolFile *symfile)
613 MonoDebuggerRangeInfo *retval;
614 guint32 size, chunks;
616 if (!symfile->range_table) {
617 size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE;
618 symfile->range_table = g_malloc0 (size);
619 symfile->num_range_entries = 1;
620 return symfile->range_table;
623 if (!((symfile->num_range_entries + 1) % RANGE_TABLE_CHUNK_SIZE)) {
624 chunks = (symfile->num_range_entries + 1) / RANGE_TABLE_CHUNK_SIZE;
625 size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE * (chunks + 1);
627 symfile->range_table = g_realloc (symfile->range_table, size);
630 retval = symfile->range_table + symfile->num_range_entries;
631 symfile->num_range_entries++;
635 static MonoDebuggerClassInfo *
636 allocate_class_entry (MonoDebuggerSymbolFile *symfile)
638 MonoDebuggerClassInfo *retval;
639 MonoDebuggerClassTable *table;
642 if (!symfile->class_table_start) {
643 table = g_new0 (MonoDebuggerClassTable, 1);
644 symfile->class_table_start = symfile->current_class_table = table;
646 size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE;
647 table->data = g_malloc0 (size);
648 table->size = CLASS_TABLE_CHUNK_SIZE;
654 table = symfile->current_class_table;
655 if (table->index >= table->size) {
656 table = g_new0 (MonoDebuggerClassTable, 1);
658 symfile->current_class_table->next = table;
659 symfile->current_class_table = table;
661 size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE;
662 table->data = g_malloc0 (size);
663 table->size = CLASS_TABLE_CHUNK_SIZE;
669 retval = table->data + table->index;
675 * Allocate a new entry of size `size' in the type table.
676 * Returns the global offset which is to be used to reference this type and
677 * a pointer (in the `ptr' argument) which is to be used to write the type.
680 allocate_type_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr)
685 g_assert (size + 4 < TYPE_TABLE_CHUNK_SIZE);
686 g_assert (ptr != NULL);
688 /* Initialize things if necessary. */
689 if (!table->current_type_table) {
690 table->current_type_table = g_malloc0 (TYPE_TABLE_CHUNK_SIZE);
691 table->type_table_size = TYPE_TABLE_CHUNK_SIZE;
692 table->type_table_chunk_size = TYPE_TABLE_CHUNK_SIZE;
693 table->type_table_offset = MONO_DEBUGGER_TYPE_MAX + 1;
697 /* First let's check whether there's still enough room in the current_type_table. */
698 if (table->type_table_offset + size + 4 < table->type_table_size) {
699 retval = table->type_table_offset;
700 table->type_table_offset += size + 4;
701 data = ((guint8 *) table->current_type_table) + retval - table->type_table_start;
702 *(gint32 *) data = size;
703 data += sizeof(gint32);
708 /* Add the current_type_table to the type_tables vector and ... */
709 if (!table->type_tables) {
710 guint32 tsize = sizeof (gpointer) * TYPE_TABLE_PTR_CHUNK_SIZE;
711 table->type_tables = g_malloc0 (tsize);
714 if (!((table->num_type_tables + 1) % TYPE_TABLE_PTR_CHUNK_SIZE)) {
715 guint32 chunks = (table->num_type_tables + 1) / TYPE_TABLE_PTR_CHUNK_SIZE;
716 guint32 tsize = sizeof (gpointer) * TYPE_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
718 table->type_tables = g_realloc (table->type_tables, tsize);
721 table->type_tables [table->num_type_tables++] = table->current_type_table;
723 /* .... allocate a new current_type_table. */
724 table->current_type_table = g_malloc0 (TYPE_TABLE_CHUNK_SIZE);
725 table->type_table_start = table->type_table_offset = table->type_table_size;
726 table->type_table_size += TYPE_TABLE_CHUNK_SIZE;
732 * Allocate a new entry of size `size' in the misc table.
733 * Returns the global offset which is to be used to reference this entry and
734 * a pointer (in the `ptr' argument) which is to be used to write the entry.
737 allocate_misc_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr)
742 g_assert (size + 4 < MISC_TABLE_CHUNK_SIZE);
743 g_assert (ptr != NULL);
745 /* Initialize things if necessary. */
746 if (!table->current_misc_table) {
747 table->current_misc_table = g_malloc0 (MISC_TABLE_CHUNK_SIZE);
748 table->misc_table_size = MISC_TABLE_CHUNK_SIZE;
749 table->misc_table_chunk_size = MISC_TABLE_CHUNK_SIZE;
750 table->misc_table_offset = 1;
754 /* First let's check whether there's still enough room in the current_misc_table. */
755 if (table->misc_table_offset + size + 4 < table->misc_table_size) {
756 retval = table->misc_table_offset;
757 table->misc_table_offset += size + 4;
758 data = ((guint8 *) table->current_misc_table) + retval - table->misc_table_start;
759 *(gint32 *) data = size;
760 data += sizeof(gint32);
765 /* Add the current_misc_table to the misc_tables vector and ... */
766 if (!table->misc_tables) {
767 guint32 tsize = sizeof (gpointer) * MISC_TABLE_PTR_CHUNK_SIZE;
768 table->misc_tables = g_malloc0 (tsize);
771 if (!((table->num_misc_tables + 1) % MISC_TABLE_PTR_CHUNK_SIZE)) {
772 guint32 chunks = (table->num_misc_tables + 1) / MISC_TABLE_PTR_CHUNK_SIZE;
773 guint32 tsize = sizeof (gpointer) * MISC_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
775 table->misc_tables = g_realloc (table->misc_tables, tsize);
778 table->misc_tables [table->num_misc_tables++] = table->current_misc_table;
780 /* .... allocate a new current_misc_table. */
781 table->current_misc_table = g_malloc0 (MISC_TABLE_CHUNK_SIZE);
782 table->misc_table_start = table->misc_table_offset = table->misc_table_size;
783 table->misc_table_size += MISC_TABLE_CHUNK_SIZE;
789 property_is_static (MonoProperty *prop)
797 return method->flags & METHOD_ATTRIBUTE_STATIC;
801 event_is_static (MonoEvent *ev)
807 return method->flags & METHOD_ATTRIBUTE_STATIC;
811 do_write_class (MonoDebuggerSymbolTable *table, MonoClass *klass, MonoDebuggerClassInfo *cinfo)
813 guint8 buffer [BUFSIZ], *ptr = buffer, *old_ptr;
814 GPtrArray *methods = NULL, *static_methods = NULL, *ctors = NULL;
815 int num_fields = 0, num_static_fields = 0, num_properties = 0, num_static_properties = 0;
816 int num_events = 0, num_static_events = 0;
817 int num_methods = 0, num_static_methods = 0, num_params = 0, num_static_params = 0, base_offset = 0;
818 int num_ctors = 0, num_ctor_params = 0;
819 int field_info_size = 0, static_field_info_size = 0, property_info_size = 0, event_info_size = 0, static_event_info_size = 0;
820 int static_property_info_size = 0, method_info_size = 0, static_method_info_size = 0;
821 int ctor_info_size = 0, iface_info_size = 0;
822 guint32 size, data_size, offset, data_offset;
823 GHashTable *method_slots = NULL;
826 if (klass->init_pending)
827 g_warning (G_STRLOC ": %p - %s.%s", klass, klass->name_space, klass->name);
828 g_assert (!klass->init_pending);
829 mono_class_init (klass);
831 offset = GPOINTER_TO_UINT (g_hash_table_lookup (class_table, klass));
835 if (klass->enumtype) {
836 offset = allocate_type_entry (table, 13, &ptr);
838 cinfo->type_info = offset;
839 g_hash_table_insert (class_table, klass, GUINT_TO_POINTER (offset));
841 *ptr++ = MONO_DEBUGGER_TYPE_KIND_ENUM;
842 WRITE_UINT32 (ptr, klass->instance_size);
843 WRITE_UINT32 (ptr, MONO_DEBUGGER_TYPE_ENUM);
844 WRITE_UINT32 (ptr, write_type (table, klass->enum_basetype));
848 for (i = 0; i < klass->field.count; i++)
849 if (!(klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
854 for (i = 0; i < klass->property.count; i++)
855 if (!property_is_static (&klass->properties [i]))
858 ++num_static_properties;
860 for (i = 0; i < klass->event.count; i++)
861 if (!event_is_static (&klass->events [i]))
866 method_slots = g_hash_table_new (NULL, NULL);
867 methods = g_ptr_array_new ();
868 static_methods = g_ptr_array_new ();
869 ctors = g_ptr_array_new ();
871 for (i = 0; i < klass->method.count; i++) {
872 MonoMethod *method = klass->methods [i];
874 if (!strcmp (method->name, ".cctor"))
876 if (!((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))
879 if (!strcmp (method->name, ".ctor")) {
881 num_ctor_params += method->signature->param_count;
882 g_ptr_array_add (ctors, method);
886 if (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME)
889 if (method->slot != -1) {
890 if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
892 g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
895 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
896 ++num_static_methods;
897 num_static_params += method->signature->param_count;
898 g_ptr_array_add (static_methods, method);
901 num_params += method->signature->param_count;
902 g_ptr_array_add (methods, method);
906 g_hash_table_destroy (method_slots);
908 field_info_size = num_fields * 8;
909 static_field_info_size = num_static_fields * 8;
910 property_info_size = num_properties * (4 + 2 * sizeof (gpointer));
911 static_property_info_size = num_static_properties * (4 + 2 * sizeof (gpointer));
912 event_info_size = num_events * (4 + 2 * sizeof (gpointer));
913 static_event_info_size = num_static_events * (4 + 2 * sizeof (gpointer));
914 method_info_size = num_methods * (4 + 2 * sizeof (gpointer)) + num_params * 4;
915 static_method_info_size = num_static_methods * (4 + 2 * sizeof (gpointer)) +
916 num_static_params * 4;
917 ctor_info_size = num_ctors * (4 + 2 * sizeof (gpointer)) + num_ctor_params * 4;
918 iface_info_size = klass->interface_count * 4;
920 size = 90 + sizeof (gpointer) + field_info_size + static_field_info_size +
921 property_info_size + static_property_info_size + event_info_size +
922 static_event_info_size + method_info_size + static_method_info_size +
923 ctor_info_size + iface_info_size;
927 offset = allocate_type_entry (table, data_size, &ptr);
931 cinfo->type_info = offset;
933 g_hash_table_insert (class_table, klass, GUINT_TO_POINTER (offset));
935 *ptr++ = MONO_DEBUGGER_TYPE_KIND_CLASS_INFO;
937 if (klass->valuetype)
938 base_offset = - sizeof (MonoObject);
940 WRITE_UINT32 (ptr, klass->instance_size + base_offset);
941 *ptr++ = klass->valuetype;
942 WRITE_POINTER (ptr, klass);
944 WRITE_UINT32 (ptr, num_fields);
945 WRITE_UINT32 (ptr, data_offset);
946 data_offset += field_info_size;
947 WRITE_UINT32 (ptr, num_properties);
948 WRITE_UINT32 (ptr, data_offset);
949 data_offset += property_info_size;
950 WRITE_UINT32 (ptr, num_events);
951 WRITE_UINT32 (ptr, data_offset);
952 data_offset += event_info_size;
953 WRITE_UINT32 (ptr, num_methods);
954 WRITE_UINT32 (ptr, data_offset);
955 data_offset += method_info_size;
956 WRITE_UINT32 (ptr, num_static_fields);
957 WRITE_UINT32 (ptr, data_offset);
958 data_offset += static_field_info_size;
959 WRITE_UINT32 (ptr, num_static_properties);
960 WRITE_UINT32 (ptr, data_offset);
961 data_offset += static_property_info_size;
962 WRITE_UINT32 (ptr, num_static_events);
963 WRITE_UINT32 (ptr, data_offset);
964 data_offset += static_event_info_size;
965 WRITE_UINT32 (ptr, num_static_methods);
966 WRITE_UINT32 (ptr, data_offset);
967 data_offset += static_method_info_size;
968 WRITE_UINT32 (ptr, num_ctors);
969 WRITE_UINT32 (ptr, data_offset);
970 data_offset += ctor_info_size;
971 WRITE_UINT32 (ptr, klass->interface_count);
972 WRITE_UINT32 (ptr, data_offset);
973 data_offset += iface_info_size;
975 if (klass->parent && (klass->parent != mono_defaults.object_class))
976 WRITE_UINT32 (ptr, write_class (table, klass->parent));
978 WRITE_UINT32 (ptr, 0);
980 for (i = 0; i < klass->field.count; i++) {
981 if (klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC)
984 WRITE_UINT32 (ptr, klass->fields [i].offset + base_offset);
985 WRITE_UINT32 (ptr, write_type (table, klass->fields [i].type));
988 for (i = 0; i < klass->property.count; i++) {
989 if (property_is_static (&klass->properties [i]))
992 if (klass->properties [i].get)
993 WRITE_UINT32 (ptr, write_type (table, klass->properties [i].get->signature->ret));
995 WRITE_UINT32 (ptr, 0);
996 WRITE_POINTER (ptr, klass->properties [i].get);
997 WRITE_POINTER (ptr, klass->properties [i].set);
1000 for (i = 0; i < klass->event.count; i++) {
1001 if (event_is_static (&klass->events[i]))
1004 if (klass->events [i].add) {
1005 WRITE_UINT32 (ptr, write_type (table, klass->events [i].add->signature->params[0]));
1008 g_warning ("event add method not defined");
1009 WRITE_UINT32 (ptr, 0);
1011 WRITE_POINTER (ptr, klass->events [i].add);
1012 WRITE_POINTER (ptr, klass->events [i].remove);
1016 for (i = 0; i < methods->len; i++) {
1017 MonoMethod *method = g_ptr_array_index (methods, i);
1020 WRITE_POINTER (ptr, method);
1021 if ((method->signature->ret) && (method->signature->ret->type != MONO_TYPE_VOID))
1022 WRITE_UINT32 (ptr, write_type (table, method->signature->ret));
1024 WRITE_UINT32 (ptr, 0);
1025 WRITE_UINT32 (ptr, method->signature->param_count);
1026 for (j = 0; j < method->signature->param_count; j++)
1027 WRITE_UINT32 (ptr, write_type (table, method->signature->params [j]));
1030 g_ptr_array_free (methods, FALSE);
1032 for (i = 0; i < klass->field.count; i++) {
1033 if (!(klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
1036 WRITE_UINT32 (ptr, klass->fields [i].offset);
1037 WRITE_UINT32 (ptr, write_type (table, klass->fields [i].type));
1040 for (i = 0; i < klass->property.count; i++) {
1041 if (!property_is_static (&klass->properties [i]))
1044 if (klass->properties [i].get)
1045 WRITE_UINT32 (ptr, write_type (table, klass->properties [i].get->signature->ret));
1047 WRITE_UINT32 (ptr, 0);
1048 WRITE_POINTER (ptr, klass->properties [i].get);
1049 WRITE_POINTER (ptr, klass->properties [i].set);
1052 for (i = 0; i < klass->event.count; i++) {
1053 if (!event_is_static (&klass->events[i]))
1056 if (klass->events [i].add) {
1057 WRITE_UINT32 (ptr, write_type (table, klass->events [i].add->signature->params[0]));
1060 g_warning ("event add method not defined");
1061 WRITE_UINT32 (ptr, 0);
1063 WRITE_POINTER (ptr, klass->events [i].add);
1064 WRITE_POINTER (ptr, klass->events [i].remove);
1068 for (i = 0; i < static_methods->len; i++) {
1069 MonoMethod *method = g_ptr_array_index (static_methods, i);
1072 WRITE_POINTER (ptr, method);
1073 if ((method->signature->ret) && (method->signature->ret->type != MONO_TYPE_VOID))
1074 WRITE_UINT32 (ptr, write_type (table, method->signature->ret));
1076 WRITE_UINT32 (ptr, 0);
1077 WRITE_UINT32 (ptr, method->signature->param_count);
1078 for (j = 0; j < method->signature->param_count; j++)
1079 WRITE_UINT32 (ptr, write_type (table, method->signature->params [j]));
1082 g_ptr_array_free (static_methods, FALSE);
1084 for (i = 0; i < ctors->len; i++) {
1085 MonoMethod *ctor = g_ptr_array_index (ctors, i);
1088 WRITE_POINTER (ptr, ctor);
1089 WRITE_UINT32 (ptr, 0);
1090 WRITE_UINT32 (ptr, ctor->signature->param_count);
1091 for (j = 0; j < ctor->signature->param_count; j++)
1092 WRITE_UINT32 (ptr, write_type (table, ctor->signature->params [j]));
1095 g_ptr_array_free (ctors, FALSE);
1097 for (i = 0; i < klass->interface_count; i++)
1098 WRITE_UINT32 (ptr, write_class (table, klass->interfaces [i]));
1100 if (ptr - old_ptr != data_size) {
1101 g_warning (G_STRLOC ": %d,%d,%d", ptr - old_ptr, data_size, sizeof (gpointer));
1103 g_warning (G_STRLOC ": %s.%s", klass->name_space, klass->name);
1104 g_assert_not_reached ();
1111 * Adds type `type' to the type table and returns its offset.
1114 write_type (MonoDebuggerSymbolTable *table, MonoType *type)
1116 guint8 buffer [BUFSIZ], *ptr = buffer;
1117 guint32 size, offset;
1120 offset = GPOINTER_TO_UINT (g_hash_table_lookup (type_table, type));
1124 klass = mono_class_from_mono_type (type);
1125 if (type->type == MONO_TYPE_CLASS)
1126 return write_class (table, klass);
1128 // mono_class_init (klass);
1130 switch (type->type) {
1131 case MONO_TYPE_VOID:
1132 return MONO_DEBUGGER_TYPE_VOID;
1134 case MONO_TYPE_BOOLEAN:
1135 return MONO_DEBUGGER_TYPE_BOOLEAN;
1138 return MONO_DEBUGGER_TYPE_I1;
1141 return MONO_DEBUGGER_TYPE_U1;
1143 case MONO_TYPE_CHAR:
1144 return MONO_DEBUGGER_TYPE_CHAR;
1147 return MONO_DEBUGGER_TYPE_I2;
1150 return MONO_DEBUGGER_TYPE_U2;
1153 return MONO_DEBUGGER_TYPE_I4;
1156 return MONO_DEBUGGER_TYPE_U4;
1159 return MONO_DEBUGGER_TYPE_I8;
1162 return MONO_DEBUGGER_TYPE_U8;
1165 return MONO_DEBUGGER_TYPE_R4;
1168 return MONO_DEBUGGER_TYPE_R8;
1170 case MONO_TYPE_STRING:
1171 return MONO_DEBUGGER_TYPE_STRING;
1174 return MONO_DEBUGGER_TYPE_I;
1177 return MONO_DEBUGGER_TYPE_U;
1179 case MONO_TYPE_SZARRAY: {
1182 *ptr++ = MONO_DEBUGGER_TYPE_KIND_SZARRAY;
1183 WRITE_UINT32 (ptr, sizeof (MonoArray));
1184 WRITE_UINT32 (ptr, MONO_DEBUGGER_TYPE_ARRAY);
1185 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
1186 *ptr++ = sizeof (array.max_length);
1187 *ptr++ = (guint8*)&array.vector - (guint8*)&array;
1188 WRITE_UINT32 (ptr, write_type (table, &type->data.klass->byval_arg));
1192 case MONO_TYPE_ARRAY: {
1194 MonoArrayBounds bounds;
1196 *ptr++ = MONO_DEBUGGER_TYPE_KIND_ARRAY;
1197 WRITE_UINT32 (ptr, sizeof (MonoArray));
1198 WRITE_UINT32 (ptr, MONO_DEBUGGER_TYPE_ARRAY);
1199 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
1200 *ptr++ = sizeof (array.max_length);
1201 *ptr++ = (guint8*)&array.vector - (guint8*)&array;
1202 *ptr++ = klass->rank;
1203 *ptr++ = (guint8*)&array.bounds - (guint8*)&array;
1204 *ptr++ = sizeof (MonoArrayBounds);
1205 *ptr++ = (guint8*)&bounds.lower_bound - (guint8*)&bounds;
1206 *ptr++ = sizeof (bounds.lower_bound);
1207 *ptr++ = (guint8*)&bounds.length - (guint8*)&bounds;
1208 *ptr++ = sizeof (bounds.length);
1209 WRITE_UINT32 (ptr, write_type (table, &type->data.array->eklass->byval_arg));
1213 case MONO_TYPE_VALUETYPE:
1214 case MONO_TYPE_CLASS:
1215 case MONO_TYPE_GENERICINST:
1216 case MONO_TYPE_OBJECT:
1217 return write_class (table, klass);
1220 *ptr++ = MONO_DEBUGGER_TYPE_KIND_POINTER;
1221 WRITE_UINT32 (ptr, sizeof (gpointer));
1222 WRITE_UINT32 (ptr, write_type (table, type->data.type));
1226 /* g_message (G_STRLOC ": %s.%s - %p - %d", klass->name_space, klass->name, klass, type->type); */
1227 *ptr++ = MONO_DEBUGGER_TYPE_KIND_UNKNOWN;
1228 WRITE_UINT32 (ptr, klass->instance_size);
1229 WRITE_UINT32 (ptr, write_class (table, klass));
1233 size = ptr - buffer;
1234 offset = allocate_type_entry (mono_debugger_symbol_table, size, &ptr);
1235 memcpy (ptr, buffer, size);
1240 MonoReflectionMethod *
1241 ves_icall_MonoDebugger_GetMethod (MonoReflectionAssembly *assembly, guint32 token)
1245 method = mono_get_method (mono_assembly_get_image (assembly->assembly), token, NULL);
1247 return mono_method_get_object (mono_domain_get (), method, NULL);
1251 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionAssembly *assembly, MonoReflectionMethod *method)
1253 return method->method->token;
1256 MonoReflectionType *
1257 ves_icall_MonoDebugger_GetType (MonoReflectionAssembly *assembly, guint32 token)
1261 klass = mono_class_get (mono_assembly_get_image (assembly->assembly), token);
1263 g_warning (G_STRLOC ": %x", token);
1267 return mono_type_get_object (mono_domain_get (), &klass->byval_arg);
1270 MonoReflectionType *
1271 ves_icall_MonoDebugger_GetLocalTypeFromSignature (MonoReflectionAssembly *assembly, MonoArray *signature)
1279 MONO_CHECK_ARG_NULL (assembly);
1280 MONO_CHECK_ARG_NULL (signature);
1282 domain = mono_domain_get();
1283 image = mono_assembly_get_image (assembly->assembly);
1285 ptr = mono_array_addr (signature, char, 0);
1286 g_assert (*ptr++ == 0x07);
1287 len = mono_metadata_decode_value (ptr, &ptr);
1288 g_assert (len == 1);
1290 type = mono_metadata_parse_type (image, MONO_PARSE_LOCAL, 0, ptr, &ptr);
1292 return mono_type_get_object (domain, type);
1296 mono_debugger_event (MonoDebuggerEvent event, gpointer data, guint32 arg)
1298 if (mono_debugger_event_handler)
1299 (* mono_debugger_event_handler) (event, data, arg);
1303 mono_debugger_cleanup (void)
1305 /* Do nothing yet. */
1309 * Debugger breakpoint interface.
1311 * This interface is used to insert breakpoints on methods which are not yet JITed.
1312 * The debugging code keeps a list of all such breakpoints and automatically inserts the
1313 * breakpoint when the method is JITed.
1316 static GPtrArray *breakpoints = NULL;
1319 mono_debugger_insert_breakpoint_full (MonoMethodDesc *desc)
1321 static int last_breakpoint_id = 0;
1322 MonoDebuggerBreakpointInfo *info;
1324 info = g_new0 (MonoDebuggerBreakpointInfo, 1);
1326 info->index = ++last_breakpoint_id;
1329 breakpoints = g_ptr_array_new ();
1331 g_ptr_array_add (breakpoints, info);
1337 mono_debugger_remove_breakpoint (int breakpoint_id)
1344 for (i = 0; i < breakpoints->len; i++) {
1345 MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
1347 if (info->index != breakpoint_id)
1350 mono_method_desc_free (info->desc);
1351 g_ptr_array_remove (breakpoints, info);
1360 mono_debugger_insert_breakpoint (const gchar *method_name, gboolean include_namespace)
1362 MonoMethodDesc *desc;
1364 desc = mono_method_desc_new (method_name, include_namespace);
1368 return mono_debugger_insert_breakpoint_full (desc);
1372 mono_debugger_method_has_breakpoint (MonoMethod *method)
1376 if (!breakpoints || (method->wrapper_type != MONO_WRAPPER_NONE))
1379 for (i = 0; i < breakpoints->len; i++) {
1380 MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
1382 if (!mono_method_desc_full_match (info->desc, method))
1392 mono_debugger_breakpoint_callback (MonoMethod *method, guint32 index)
1394 mono_debugger_event (MONO_DEBUGGER_EVENT_BREAKPOINT, method, index);
1398 mono_debugger_unhandled_exception (gpointer addr, gpointer stack, MonoObject *exc)
1400 if (!mono_debugger_initialized)
1403 // Prevent the object from being finalized.
1404 last_exception = exc;
1405 mono_debugger_event (MONO_DEBUGGER_EVENT_UNHANDLED_EXCEPTION, exc, addr);
1410 mono_debugger_handle_exception (gpointer addr, gpointer stack, MonoObject *exc)
1412 MonoDebuggerExceptionInfo info;
1414 if (!mono_debugger_initialized)
1417 // Prevent the object from being finalized.
1418 last_exception = exc;
1420 info.stack_pointer = stack;
1421 info.exception_obj = exc;
1423 mono_debugger_event (MONO_DEBUGGER_EVENT_EXCEPTION, &info, addr);
1427 get_exception_message (MonoObject *exc)
1429 char *message = NULL;
1435 if (mono_object_isinst (exc, mono_defaults.exception_class)) {
1436 klass = exc->vtable->klass;
1438 while (klass && method == NULL) {
1439 for (i = 0; i < klass->method.count; ++i) {
1440 method = klass->methods [i];
1441 if (!strcmp ("ToString", method->name) &&
1442 method->signature->param_count == 0 &&
1443 method->flags & METHOD_ATTRIBUTE_VIRTUAL &&
1444 method->flags & METHOD_ATTRIBUTE_PUBLIC) {
1451 klass = klass->parent;
1456 str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
1458 message = mono_string_to_utf8 (str);
1465 mono_debugger_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
1470 if (method->klass->valuetype && (obj != NULL))
1471 obj = mono_value_box (mono_domain_get (), method->klass, obj);
1473 if (!strcmp (method->name, ".ctor")) {
1474 retval = obj = mono_object_new (mono_domain_get (), method->klass);
1476 mono_runtime_invoke (method, obj, params, exc);
1478 retval = mono_runtime_invoke (method, obj, params, exc);
1480 if (!exc || (*exc == NULL))
1483 message = get_exception_message (*exc);
1485 *exc = (MonoObject *) mono_string_new_wrapper (message);
1493 mono_debugger_lookup_type (const gchar *type_name)
1497 mono_debugger_lock ();
1499 for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
1500 MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
1505 name = g_strdup (type_name);
1506 type = mono_reflection_type_from_name (name, symfile->image);
1511 offset = write_type (mono_debugger_symbol_table, type);
1513 mono_debugger_unlock ();
1517 mono_debugger_unlock ();
1522 mono_debugger_lookup_assembly (const gchar *name)
1524 MonoAssembly *assembly;
1525 MonoImageOpenStatus status;
1528 mono_debugger_lock ();
1531 for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
1532 MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
1534 if (!strcmp (symfile->image_file, name)) {
1535 mono_debugger_unlock ();
1540 assembly = mono_assembly_open (name, &status);
1542 if (status != MONO_IMAGE_OK) {
1543 g_warning (G_STRLOC ": Cannot open image `%s'", name);
1544 mono_debugger_unlock ();
1548 must_reload_symtabs = TRUE;
1553 mono_debugger_add_wrapper (MonoMethod *wrapper, MonoDebugMethodJitInfo *jit, gpointer addr)
1555 guint32 size, offset;
1558 if (!mono_debugger_symbol_table)
1561 size = strlen (wrapper->name) + 5 + 5 * sizeof (gpointer);
1563 offset = allocate_misc_entry (mono_debugger_symbol_table, size, &ptr);
1565 WRITE_UINT32 (ptr, MONO_DEBUGGER_MISC_ENTRY_TYPE_WRAPPER);
1566 WRITE_STRING (ptr, wrapper->name);
1567 WRITE_POINTER (ptr, jit->code_start);
1568 WRITE_POINTER (ptr, jit->code_start + jit->code_size);
1569 WRITE_POINTER (ptr, addr);
1570 WRITE_POINTER (ptr, jit->code_start + jit->prologue_end);
1571 WRITE_POINTER (ptr, jit->code_start + jit->epilogue_begin);