MonoSymbolTable *mono_symbol_table = NULL;
MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
+guint32 mono_debug_debugger_version = -1;
static gboolean in_the_mono_debugger = FALSE;
static gboolean mono_debug_initialized = FALSE;
static GHashTable *method_hash = NULL;
-static MonoDebugHandle *mono_debug_open_image (MonoImage *image);
+static MonoDebugHandle *mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size);
+
static void mono_debug_close_image (MonoDebugHandle *debug);
static MonoDebugHandle *_mono_debug_get_image (MonoImage *image);
void
mono_debug_init_1 (MonoDomain *domain)
{
- MonoDebugHandle *handle = mono_debug_open_image (mono_get_corlib ());
+ MonoDebugHandle *handle = mono_debug_open_image (mono_get_corlib (), NULL, 0);
- if (in_the_mono_debugger)
- mono_debugger_add_builtin_types (handle);
+ mono_symbol_table->corlib = handle;
}
/*
void
mono_debug_init_2 (MonoAssembly *assembly)
{
- mono_debug_open_image (mono_assembly_get_image (assembly));
+ mono_debug_open_image (mono_assembly_get_image (assembly), NULL, 0);
+}
+
+/*
+ * Initialize debugging support - part 2.
+ *
+ * This method must be called between loading the image and loading the assembly.
+ */
+void
+mono_debug_init_2_memory (MonoImage *image, const guint8 *raw_contents, int size)
+{
+ mono_debug_open_image (image, raw_contents, size);
+}
+
+
+gboolean
+mono_debug_using_mono_debugger (void)
+{
+ return in_the_mono_debugger;
}
void
}
static MonoDebugHandle *
-mono_debug_open_image (MonoImage *image)
+mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
{
MonoDebugHandle *handle;
g_hash_table_insert (mono_debug_handles, image, handle);
- handle->symfile = mono_debug_open_mono_symbol_file (handle, in_the_mono_debugger);
+ handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, in_the_mono_debugger);
if (in_the_mono_debugger)
mono_debugger_add_symbol_file (handle);
mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
{
mono_debugger_lock ();
- mono_debug_open_image (mono_assembly_get_image (assembly));
+ mono_debug_open_image (mono_assembly_get_image (assembly), NULL, 0);
mono_debugger_unlock ();
}
return;
if (handle->symfile)
- data->minfo = mono_debug_find_method (handle, data->method);
+ data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
}
static MonoDebugMethodInfo *
return data.minfo;
}
+/**
+ * mono_debug_lookup_method:
+ *
+ * Lookup symbol file information for the method @method. The returned
+ * `MonoDebugMethodInfo' is a private structure, but it can be passed to
+ * mono_debug_symfile_lookup_location().
+ */
+MonoDebugMethodInfo *
+mono_debug_lookup_method (MonoMethod *method)
+{
+ MonoDebugMethodInfo *minfo;
+
+ mono_debugger_lock ();
+ minfo = _mono_debug_lookup_method (method);
+ mono_debugger_unlock ();
+ return minfo;
+}
+
static inline void
write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
{
{
MonoMethodHeader *header;
MonoDebugWrapperData *wrapper;
- char buffer [BUFSIZ];
+ guint8 buffer [BUFSIZ];
guint8 *ptr, *oldptr;
guint32 i, size, total_size, max_size;
gint32 last_il_offset = 0, last_native_offset = 0;
+ const unsigned char* il_code;
+ guint32 il_codesize;
if (!in_the_mono_debugger)
return NULL;
mono_debugger_lock ();
- header = ((MonoMethodNormal *) method)->header;
+ header = mono_method_get_header (method);
max_size = 28 * jit->num_line_numbers;
if (max_size > BUFSIZ)
wrapper->code_size = jit->code_size;
wrapper->name = mono_method_full_name (method, TRUE);
+ il_code = mono_method_header_get_code (header, &il_codesize, NULL);
wrapper->cil_code = mono_disasm_code (
- NULL, method, header->code, header->code + header->code_size);
+ NULL, method, il_code, il_code + il_codesize);
memcpy (&wrapper->data, oldptr, size);
mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
{
MonoDebugMethodAddress *address;
- char buffer [BUFSIZ];
+ guint8 buffer [BUFSIZ];
guint8 *ptr, *oldptr;
guint32 i, size, total_size, max_size;
gint32 last_il_offset = 0, last_native_offset = 0;
MonoDebugMethodInfo *minfo;
MethodHashEntry *hash;
- if (method->is_inflated)
- return NULL;
-
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
handle = _mono_debug_get_image (method->klass->image);
if (!handle || !handle->symfile || !handle->symfile->offset_table) {
+ mono_debug_add_wrapper (method, jit);
mono_debugger_unlock ();
return NULL;
}
for (i = 0; i < jit->num_lexical_blocks; i ++) {
MonoDebugLexicalBlockEntry *jit_lbe = &jit->lexical_blocks [i];
MonoSymbolFileLexicalBlockEntry *minfo_lbe = &minfo->lexical_blocks [i];
- jit_lbe->il_start_offset = minfo_lbe->_start_offset;
+ jit_lbe->il_start_offset = read32 (&(minfo_lbe->_start_offset));
jit_lbe->native_start_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_start_offset);
- jit_lbe->il_end_offset = minfo_lbe->_end_offset;
+ jit_lbe->il_end_offset = read32 (&(minfo_lbe->_end_offset));
jit_lbe->native_end_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_end_offset);
}
{
MonoDebugHandle *handle;
MonoDebugClassEntry *entry;
- char buffer [BUFSIZ];
+ guint8 buffer [BUFSIZ];
guint8 *ptr, *oldptr;
guint32 size, total_size, max_size;
int base_offset = 0;
if (max_size > BUFSIZ)
g_free (oldptr);
- mono_debugger_start_add_type (handle, klass);
+ mono_debugger_add_type (handle, klass);
}
static MonoDebugMethodJitInfo *
return mono_debug_read_method (address);
}
+MonoDebugMethodJitInfo *
+mono_debug_find_method (MonoDebugMethodInfo *minfo, MonoDomain *domain)
+{
+ MonoDebugMethodJitInfo *res;
+ mono_debugger_lock ();
+ res = find_method (minfo, domain);
+ mono_debugger_unlock ();
+ return res;
+}
+
static gint32
il_offset_from_address (MonoDebugMethodInfo *minfo, MonoDomain *domain, guint32 native_offset)
{
}
/**
- * mono_debug_source_location_from_address:
- * @method:
- * @address:
- * @line_number:
- * @domain:
- *
- * Used by the exception code to get a source location from a machine address.
+ * mono_debug_lookup_source_location:
+ * @address: Native offset within the @method's machine code.
*
- * Returns: a textual representation of the specified address which is suitable to be displayed to
- * the user (for instance "/home/martin/monocvs/debugger/test/Y.cs:8").
+ * Lookup the source code corresponding to the machine instruction located at
+ * native offset @address within @method.
*
- * If the optional @line_number argument is not NULL, the line number is stored there and just the
- * source file is returned (ie. it'd return "/home/martin/monocvs/debugger/test/Y.cs" and store the
- * line number 8 in the variable pointed to by @line_number).
+ * The returned `MonoDebugSourceLocation' contains both file / line number
+ * information and the corresponding IL offset. It must be freed by
+ * mono_debug_free_source_location().
*/
-gchar *
-mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number,
- MonoDomain *domain)
+MonoDebugSourceLocation *
+mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
{
MonoDebugMethodInfo *minfo;
- char *res = NULL;
+ MonoDebugSourceLocation *location;
gint32 offset;
if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
}
offset = il_offset_from_address (minfo, domain, address);
-
- if (offset >= 0)
- res = mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
-
- mono_debugger_unlock ();
- return res;
-}
-
-/**
- * mono_debug_source_location_from_il_offset:
- * @method:
- * @offset:
- * @line_number:
- *
- * Used by the exception code to get a source location from an IL offset.
- *
- * Returns a textual representation of the specified address which is suitable to be displayed to
- * the user (for instance "/home/martin/monocvs/debugger/test/Y.cs:8").
- *
- * If the optional @line_number argument is not NULL, the line number is stored there and just the
- * source file is returned (ie. it'd return "/home/martin/monocvs/debugger/test/Y.cs" and store the
- * line number 8 in the variable pointed to by @line_number).
- */
-gchar *
-mono_debug_source_location_from_il_offset (MonoMethod *method, guint32 offset, guint32 *line_number)
-{
- char *res;
- MonoDebugMethodInfo *minfo;
-
- if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
- return NULL;
-
- mono_debugger_lock ();
- minfo = _mono_debug_lookup_method (method);
- if (!minfo || !minfo->handle || !minfo->handle->symfile) {
+ if (offset < 0) {
mono_debugger_unlock ();
return NULL;
}
- res = mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+ location = mono_debug_symfile_lookup_location (minfo, offset);
mono_debugger_unlock ();
- return res;
+ return location;
}
/**
- * mono_debug_il_offset_from_address:
- * @method:
- * @address:
- * @domain:
+ * mono_debug_free_source_location:
+ * @location: A `MonoDebugSourceLocation'.
*
- * Returns: the IL offset corresponding to machine address @address which is an offset
- * relative to the beginning of the method @method.
+ * Frees the @location.
*/
-gint32
-mono_debug_il_offset_from_address (MonoMethod *method, gint32 address, MonoDomain *domain)
+void
+mono_debug_free_source_location (MonoDebugSourceLocation *location)
{
- MonoDebugMethodInfo *minfo;
- gint32 res;
-
- if ((address < 0) || (mono_debug_format == MONO_DEBUG_FORMAT_NONE))
- return -1;
-
- mono_debugger_lock ();
- minfo = _mono_debug_lookup_method (method);
- if (!minfo || !minfo->il_offsets || !minfo->handle || !minfo->handle->symfile ||
- !minfo->handle->symfile->offset_table) {
- mono_debugger_unlock ();
- return -1;
+ if (location) {
+ g_free (location->source_file);
+ g_free (location);
}
-
- res = il_offset_from_address (minfo, domain, address);
- mono_debugger_unlock ();
- return res;
}
/**
- * mono_debug_address_from_il_offset:
- * @method:
- * @il_offset:
- * @domain:
+ * mono_debug_print_stack_frame:
+ * @native_offset: Native offset within the @method's machine code.
*
- * Returns: the machine address corresponding to IL offset @il_offset.
- * The returned value is an offset relative to the beginning of the method @method.
+ * Conventient wrapper around mono_debug_lookup_source_location() which can be
+ * used if you only want to use the location to print a stack frame.
*/
-gint32
-mono_debug_address_from_il_offset (MonoMethod *method, gint32 il_offset, MonoDomain *domain)
+gchar *
+mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
{
- MonoDebugMethodInfo *minfo;
- MonoDebugMethodJitInfo *jit;
- gint32 res;
+ MonoDebugSourceLocation *location;
+ gchar *fname, *ptr, *res;
- if ((il_offset < 0) || (mono_debug_format == MONO_DEBUG_FORMAT_NONE))
- return -1;
-
- mono_debugger_lock ();
- minfo = _mono_debug_lookup_method (method);
- if (!minfo || !minfo->il_offsets || !minfo->handle || !minfo->handle->symfile ||
- !minfo->handle->symfile->offset_table) {
- mono_debugger_unlock ();
- return -1;
+ fname = mono_method_full_name (method, TRUE);
+ for (ptr = fname; *ptr; ptr++) {
+ if (*ptr == ':') *ptr = '.';
}
- jit = find_method (minfo, domain);
- if (!jit) {
- mono_debugger_unlock ();
- return -1;
+ location = mono_debug_lookup_source_location (method, native_offset, domain);
+
+ if (!location) {
+ res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
+ g_free (fname);
+ return res;
}
- res = _mono_debug_address_from_il_offset (jit, il_offset);
- mono_debugger_unlock ();
+ res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
+ location->source_file, location->row);
+
+ g_free (fname);
+ mono_debug_free_source_location (location);
return res;
}
+