[Mono-list] JIT patch for stabs debugging
Martin Baulig
martin@gnome.org
10 Mar 2002 02:39:45 +0100
--=-=-=
Hi,
this afternoon I was finally tired of using Console.WriteLine (...)
for debugging and looked at `mono --stabs'.
Here's a patch which makes this finally work.
The patch does two things:
1.) Puts a NOP instruction at the start of every method.
If you use `mono --debug Something', this buts a breakpoint
instruction (INT 3) at the start of "Something" - which means
that the address of Something's first instruction changes, but
this address is already hard-coded into the stabs file.
So without the NOP instructions you need to recreate your stabs
symbol files each time you want to run mono with different --debug
arguments.
2.) Uses correct line numbers in the stabs file.
In mono_debug_add_method(), `t->cli_add' is a bytecode offset, but
not a line number in the .il file.
For instance, if t->cli_addr == 0xc, the stabs file must contain
the line number of the method's IL_000c line in the .il file.
=====
2002-03-10 Martin Baulig <martin@gnome.org>
* emit-x86.c (arch_compile_method): When emitting stabs debugging
output, put a nop instruction at the start of all functions so that
the adresses won't change when using --debug.
* debug.c (mono_debug_add_method): `tree->cli_addr' is an offset into
the bytecode area, stabs needs a line number in the .il file. Use the
new info->moffsets to get the line number.
(AssemblyDebugInfo): Added `total_lines' and `moffsets' fields.
`moffsets' is an array of `total_lines' fields (total number of lines
in the .il file); for each line in the .il field, this array contains
the bytecode offset if it's an "IL_xxxx" line, -1 if it's the last line
of a method and 0 otherwise.
(debug_load_method_lines): Read the whole .il file and initialize the
info->moffsets field.
====
--=-=-=
Content-Disposition: attachment; filename=jit-debug-patch.txt
Index: ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/jit/ChangeLog,v
retrieving revision 1.121
diff -u -u -r1.121 ChangeLog
--- ChangeLog 2002/03/08 06:08:46 1.121
+++ ChangeLog 2002/03/09 21:48:12
@@ -1,3 +1,25 @@
+2002-03-10 Martin Baulig <martin@gnome.org>
+
+ * emit-x86.c (arch_compile_method): When emitting stabs debugging
+ output, put a nop instruction at the start of all functions so that
+ the adresses won't change when using --debug.
+
+ * debug.c (mono_debug_add_method): `tree->cli_addr' is an offset into
+ the bytecode area, stabs needs a line number in the .il file. Use the
+ new info->moffsets to get the line number.
+ (AssemblyDebugInfo): Added `total_lines' and `moffsets' fields.
+ `moffsets' is an array of `total_lines' fields (total number of lines
+ in the .il file); for each line in the .il field, this array contains
+ the bytecode offset if it's an "IL_xxxx" line, -1 if it's the last line
+ of a method and 0 otherwise.
+ (debug_load_method_lines): Read the whole .il file and initialize the
+ info->moffsets field.
+
+2002-03-09 Martin Baulig <martin@gnome.org>
+
+ * x86.brg (DIV_UN): Clear EDX before performing the division and remove
+ the unnecessary CDQ instruction.
+
2002-03-07 Dietmar Maurer <dietmar@ximian.com>
* jit.c (mono_analyze_stack): only load addresses of value types
Index: debug.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/debug.c,v
retrieving revision 1.6
diff -u -u -r1.6 debug.c
--- debug.c 2002/02/19 06:01:21 1.6
+++ debug.c 2002/03/09 21:48:13
@@ -9,7 +9,9 @@
FILE *f;
char *filename;
char *name;
+ int total_lines;
int *mlines;
+ int *moffsets;
int nmethods;
int next_idx;
} AssemblyDebugInfo;
@@ -106,21 +108,45 @@
g_free (name);
return;
}
+
+ info->total_lines = 100;
+ info->moffsets = g_malloc (info->total_lines * sizeof (int));
+
g_free (name);
i = 0;
while (fgets (buf, sizeof (buf), f)) {
- i++;
- if (sscanf (buf, " // method line %d", &mnum) && mnum < info->nmethods) {
- while (fgets (buf, sizeof (buf), f)) {
- ++i;
- if (strstr (buf, "}"))
- break; /* internalcall or runtime method */
- if (strstr (buf, "IL_0000:"))
- break;
+ int offset = 0, pos = i;
+
+ ++i;
+ if (!sscanf (buf, " // method line %d", &mnum))
+ continue;
+
+ if (mnum >= info->nmethods)
+ break;
+
+ while (fgets (buf, sizeof (buf), f)) {
+ int newoffset;
+
+ ++i;
+ if (i + 2 >= info->total_lines) {
+ info->total_lines += 100;
+ info->moffsets = g_realloc (info->moffsets, info->total_lines * sizeof (int));
+ g_assert (info->moffsets);
+ }
+
+ if (strstr (buf, "}"))
+ break;
+
+ if (sscanf (buf, " IL_%x:", &newoffset)) {
+ offset = newoffset;
+ if (!offset)
+ pos = i;
}
- /* g_print ("method %d found at %d\n", mnum, i); */
- info->mlines [mnum] = i;
+
+ info->moffsets [i] = offset;
}
+ /* g_print ("method %d found at %d\n", mnum, pos); */
+ info->mlines [mnum] = pos;
}
fclose (f);
}
@@ -178,6 +204,7 @@
{
fclose (debug->f);
g_free (debug->mlines);
+ g_free (debug->moffsets);
g_free (debug->name);
g_free (debug->filename);
g_free (debug);
@@ -201,14 +228,16 @@
mono_debug_add_method (MonoDebugHandle* debug, MonoFlowGraph *cfg)
{
char *name;
- int line = 0;
- int i;
+ int line = 0, line_index = 0;
+ int i, print;
MonoMethod *method = cfg->method;
MonoClass *klass = method->klass;
MonoMethodSignature *sig = method->signature;
char **names = g_new (char*, sig->param_count);
AssemblyDebugInfo* info = mono_debug_open_ass (debug, klass->image);
+ print = !strcmp (method->name, "Parse") || !strcmp (method->name, "Main");
+
/* FIXME: we should mangle the name better */
name = g_strdup_printf ("%s%s%s__%s_%p", klass->name_space, klass->name_space [0]? "_": "",
klass->name, method->name, method);
@@ -222,6 +251,7 @@
*/
for (i = 0; klass->methods && i < klass->method.count; ++i) {
if (klass->methods [i] == method) {
+ line_index = klass->method.first + i + 1;
line = info->mlines [klass->method.first + i + 1];
/*g_print ("method %d found at line %d\n", klass->method.first + i + 1, line);*/
break;
@@ -232,7 +262,7 @@
* We need to output all the basic info, if we change filename...
* fprintf (info->f, ".stabs \"%s.il\",100,0,0,0\n", klass->image->assembly_name);
*/
- fprintf (info->f, ".stabs \"%s:F(0,%d)\",36,0,%d,%p\n", name, sig->ret->type, line, cfg->start);
+ fprintf (info->f, ".stabs \"%s:F(0,%d)\",36,0,%d,%p\n", name, sig->ret->type, line, cfg->start+1);
/* params */
mono_method_get_param_names (cfg->method, (const char **)names);
@@ -250,12 +280,23 @@
fprintf (info->f, ".stabs \"local_%d:(0,%d)=(0,%d)\",128,0,%d,%d\n", i, info->next_idx++, header->locals [i]->type, line, stack_offset);
}
}
+
+ fprintf (info->f, ".stabn 68,0,%d,%d\n", line, 0);
+
/* start lines of basic blocks */
for (i = 0; i < cfg->block_count; ++i) {
int j;
+
+ // mono_print_forest (cfg->bblocks [i].forest);
+
for (j = 0; j < cfg->bblocks [i].forest->len; ++j) {
MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
- fprintf (info->f, ".stabn 68,0,%d,%d\n", line + t->cli_addr, t->addr);
+ int *lines = info->moffsets + line, *k = lines;
+
+ while ((*k != -1) && (*k < t->cli_addr))
+ k++;
+
+ fprintf (info->f, ".stabn 68,0,%d,%d\n", line + (k-lines), t->addr-1);
}
}
Index: emit-x86.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/emit-x86.c,v
retrieving revision 1.61
diff -u -u -r1.61 emit-x86.c
--- emit-x86.c 2002/03/08 06:08:46 1.61
+++ emit-x86.c 2002/03/09 21:48:15
@@ -1058,6 +1058,8 @@
if (match_debug_method (method))
x86_breakpoint (cfg->code);
+ else if (mono_debug_handle)
+ x86_nop (cfg->code);
if (mono_jit_dump_forest) {
int i;
Index: x86.brg
===================================================================
RCS file: /cvs/public/mono/mono/jit/x86.brg,v
retrieving revision 1.92
diff -u -u -r1.92 x86.brg
--- x86.brg 2002/03/08 06:08:46 1.92
+++ x86.brg 2002/03/09 21:48:16
@@ -816,7 +816,7 @@
if (tree->left->reg1 != X86_EAX)
x86_mov_reg_reg (s->code, X86_EAX, tree->left->reg1, 4);
- x86_cdq (s->code);
+ x86_mov_reg_imm (s->code, X86_EDX, 0);
x86_div_reg (s->code, tree->right->reg1, FALSE);
mono_assert (tree->reg1 == X86_EAX &&
--=-=-=
After applying this patch, single stepping through a function now
actually works :-)
--
Martin Baulig
martin@gnome.org
--=-=-=--