[Mono-devel-list] [patch] stabs debugging info on --aot code

vladimir at pobox.com vladimir at pobox.com
Wed May 26 05:22:56 EDT 2004


Hi,

I've started doing some poking around at adding some basic stabs
debug info to the --aot generated assembly output.  This gives you
more useful gdb backtraces:

#0  0x00a803a6 in Hello.ComputeIt ()
   from /home/vladimir/proj/mono-cvs/test/hello.exe.so
#1  0x00a80427 in Hello.Main ()
   from /home/vladimir/proj/mono-cvs/test/hello.exe.so
#2  0x0026934b in ?? ()
#3  0x08320588 in ?? ()
#4  0x00258b08 in ?? () from /usr/local/lib/libmono.so.0
#5  0x00269330 in ?? ()
#6  0x08320588 in ?? ()
#7  0x0080f8c8 in ?? ()
#8  0x00153fad in mono_jit_compile_method (method=0x0) at mini.c:8008
#9  0x0015408e in mono_jit_runtime_invoke (method=0x8320588, obj=0x0,

(The ??'s are from stuff that I didn't --aot, also internally generated
stuff)  It's also the first step to being able to generate oprofile data
for JIT'd code, at least AOT code.  Note that the Java guys are talking
about getting oprofile data working natively with JIT'd code; someone
who has a better understanding of the JIT than I should probably jump
into this conversation:
http://marc.theaimsgroup.com/?l=oprofile-list&m=108490766726601&w=2 so that
whatever mechanism ends up in oprofile is usable for us as well.

The patch also sets use_loaded_code to TRUE if --debug is given; without
this, the symbols don't match the actual memory address (because the code
gets copied).  --debug also should be specified with --aot, to get
source file info (and, eventually, line number info).  Thinking about it,
--debug should probably control whether the stabs data is emitted or not.

Thanks,
	- Vlad

-------------- next part --------------
Index: mini/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/mini/ChangeLog,v
retrieving revision 1.552
diff -u -u -r1.552 ChangeLog
--- mini/ChangeLog	25 May 2004 22:23:23 -0000	1.552
+++ mini/ChangeLog	26 May 2004 07:55:56 -0000
@@ -1,3 +1,15 @@
+2004-05-25  Vladimir Vukicevic  <vladimir at pobox.com>
+
+	* driver.c (mono_main): call mono_aot_use_loaded_code if --debug
+	is passed
+
+	* aot.c, mini.h: mono_aot_use_loaded_code() to set use_loaded_code
+	AOT flag
+
+	* aot.c (emit_stabs_function, emit_stabs, emit_method, 
+	mono_compile_assembly): Emit primitive STABS debugging output
+	into the AOT .so; just function names for now.
+
 2004-05-26  Gonzalo Paniagua Javier <gonzalo at ximian.com>
 
 	* Makefile.am: don't distribute generated inssel.[ch] files.
Index: mini/aot.c
===================================================================
RCS file: /cvs/public/mono/mono/mini/aot.c,v
retrieving revision 1.33
diff -u -u -r1.33 aot.c
--- mini/aot.c	8 Apr 2004 18:01:12 -0000	1.33
+++ mini/aot.c	26 May 2004 07:55:56 -0000
@@ -29,6 +29,7 @@
 #include <mono/metadata/tokentype.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/mono-debug.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/marshal.h>
 #include <mono/os/gc_wrapper.h>
@@ -653,23 +654,97 @@
 
 	emit_section_change (fp, ".text", 1);
 
	fprintf (fp, ".globl %s\n", name);
 	fprintf (fp, "\t.align %d\n", align);
 	fprintf (fp, "\t.type %s,#object\n", name);
 	fprintf (fp, "\t.size %s,%d\n", name, size);
 	fprintf (fp, "%s:\n", name);
 	for (i = 0; i < size; i++) { 
		fprintf (fp, ".byte %d\n", buf [i]);
 	}
 	
 }
 #endif
 
 static void
+emit_stabs_function (FILE *fp, MonoMethod *mm, const char *mname)
+{
+	/* Emit the filename info, if its changed */
+	static gchar* aot_last_debug_dir = NULL;
+	static gchar* aot_last_debug_file = NULL;
+
+	guint32 linenum;
+	gchar *sourceloc;
+
+	sourceloc = mono_debug_source_location_from_il_offset (mm, 0, &linenum);
+	if (sourceloc) {
+		gchar *dirname, *filename;
+		gchar *slash = strrchr (sourceloc, '/');
+
+		if (slash) {
+			*slash = 0;
+			dirname = sourceloc;
+			filename = slash+1;
+		} else {
+			dirname = NULL;
+			filename = sourceloc;
+		}
+
+		if (aot_last_debug_dir == NULL ||
+			strcmp(aot_last_debug_dir, dirname) ||
+			strcmp(aot_last_debug_file, filename))
+		{
+			/* The file or the dir has changed, so we emit */
+			fprintf (fp, "\t.file \"%s\"\n", filename);
+			if (dirname)
+				fprintf (fp, "\t.stabs \"%s/\",100,0,0,0\n", dirname);
+			fprintf (fp, "\t.stabs \"%s\",100,0,0,0\n", filename);
+
+			if (aot_last_debug_dir) g_free (aot_last_debug_dir);
+			if (aot_last_debug_file) g_free (aot_last_debug_file);
+
+			aot_last_debug_dir = g_strdup (dirname);
+			aot_last_debug_file = g_strdup (filename);
+		}
+
+		g_free (sourceloc);
+	} else {
+		/* Emit dummy file */
+		fprintf (fp, "\t.file \"DUMMY\"\n");
+		fprintf (fp, "\t.stabs \"DUMMY\",100,0,0,0\n");
+	}
+	
+	if (mm->klass) {
+		fprintf (fp, "\t.stabs \"%s%s%s%s%s:F0\",36,0,0,%s\n",
+				 (mm->klass->name_space && *(mm->klass->name_space)) ? mm->klass->name_space : "",
+				 (mm->klass->name_space && *(mm->klass->name_space)) ? "." : "",
+				 mm->klass->name ? mm->klass->name : "",
+				 mm->klass->name ? "." : "",
+				 mm->name,
+				 mname);
+	} else {
+		fprintf (fp, "\t.stabs \"%s:F0\",36,0,0,%s\n",
+				 mm->name,
+				 mname);
+	}
+}
+
+static void
+emit_stabs (FILE *fp, const char *sname, const char *sargs, int type, int other, int desc, const char *value)
+{
+	fprintf (fp, "\t.stabs \"%s%s%s\",%d,%d,%d,%s\n",
+			 sname,
+			 sargs != NULL ? ":" : "",
+			 sargs != NULL ? sargs : "",
+			 type, other, desc,
+			 value != NULL ? value : "0");
+}
+
+static void
 write_string_symbol (FILE *fp, const char *name, const char *value)
 {
 	emit_section_change (fp, ".text", 1);
	fprintf (fp, ".globl %s\n", name);
 	fprintf (fp, "%s:\n", name);
 	fprintf (fp, "\t%s \"%s\"\n", AS_STRING_DIRECTIVE, value);
 }
@@ -806,7 +881,8 @@
 	emit_section_change (tmpfp, ".text", 0);
 	mname = g_strdup_printf ("m_%x", mono_metadata_token_index (method->token));
 	fprintf (tmpfp, "\t.align %d\n", func_alignment);
	fprintf (tmpfp, ".globl %s\n", mname);
+	emit_stabs_function (tmpfp, method, mname);
 #if defined(sparc)
 	fprintf (tmpfp, "\t.type %s,#function\n", mname);
 #else
@@ -1136,6 +1212,11 @@
 	acfg->image_hash = g_hash_table_new (NULL, NULL);
 	acfg->image_table = g_ptr_array_new ();
 
+    /* Set up initial stab data so that debuggers don't complain */
+	fprintf (tmpfp, "\t.file \"DUMMY\"\n");
+	fprintf (tmpfp, "\t.stabs \"DUMMY\",100,0,0,0\n");
+	emit_stabs (tmpfp, "void", "t0=0", 128, 0, 0, NULL);
+
 	write_string_symbol (tmpfp, "mono_assembly_guid" , image->guid);
 
 	write_string_symbol (tmpfp, "mono_aot_version", MONO_AOT_FILE_VERSION);
@@ -1321,10 +1402,14 @@
 	printf ("%d methods contain wrapper references (%d%%)\n", wrappercount, mcount ? (wrappercount*100)/mcount : 100);
 	printf ("%d methods contain lmf pointers (%d%%)\n", lmfcount, mcount ? (lmfcount*100)/mcount : 100);
 	printf ("%d methods have other problems (%d%%)\n", ocount, mcount ? (ocount*100)/mcount : 100);
 
 	return 0;
 }
 
-
+void
+mono_aot_use_loaded_code (gboolean use)
+{
+	use_loaded_code = use;
+}
Index: mini/driver.c
===================================================================
RCS file: /cvs/public/mono/mono/mini/driver.c,v
retrieving revision 1.51
diff -u -u -r1.51 driver.c
--- mini/driver.c	24 May 2004 10:10:28 -0000	1.51
+++ mini/driver.c	26 May 2004 07:55:56 -0000
@@ -483,6 +483,6 @@
 	MainThreadArgs *main_args = user_data;
 	MonoAssembly *assembly;
 
 	assembly = mono_domain_assembly_open (main_args->domain, main_args->file);
 	if (!assembly){
 		fprintf (stderr, "Can not open image %s\n", main_args->file);
@@ -756,8 +758,10 @@
 		break;
 	}
 
-	if (enable_debugging)
+	if (enable_debugging) {
+		mono_aot_use_loaded_code (TRUE);
 		mono_debug_init (domain, MONO_DEBUG_FORMAT_MONO);
+        }
 
 	/* Parse gac loading options before loading assemblies. */
 	if (mono_compile_aot || action == DO_EXEC) {
 
Index: mini/mini.h
===================================================================
RCS file: /cvs/public/mono/mono/mini/mini.h,v
retrieving revision 1.71
diff -u -u -r1.71 mini.h
--- mini/mini.h	20 May 2004 12:53:35 -0000	1.71
+++ mini/mini.h	26 May 2004 07:55:56 -0000
@@ -698,6 +698,7 @@
 void      mono_aot_init                     (void);
 MonoJitInfo*  mono_aot_get_method           (MonoDomain *domain,
 											 MonoMethod *method);
+void      mono_aot_use_loaded_code          (gboolean use);
 gboolean  mono_method_blittable             (MonoMethod *method);
 gboolean  mono_method_same_domain           (MonoJitInfo *caller, MonoJitInfo *callee);
 void      mono_register_opcode_emulation    (int opcode, const char* name, MonoMethodSignature *sig, gpointer func, gboolean no_throw);



More information about the Mono-devel-list mailing list