In System:
[mono.git] / web / jit-debug
index 71c4db74420ac0add58c3743c5134994023ff9de..66b4411ff07d901618781294ddfce48e13eb31d4 100644 (file)
-* How to debug your C# application with the JIT engine 
+* Debugging information
 
-       To debug a C# application you need to run the JIT in your debugger.
+       Compile your programs using the `-g' flag in MCS, that will all a special
+       resource containing debugging information to your executable.
 
-       Before you can do anything useful in a debugger, you need a symbol
-       file which tells your debugger about functions, types, line numbers
-       and such. Unfortunately, this symbol file needs to be recreated each
-       time the JIT compiles a new method since it doesn't know anything
-       about this method (especially not its memory address) before actually
-       compiling it.
+       To get stack traces with line number information, you need to run your 
+       program like this:
 
-       You have two ways of creating a symbol file:
+       <b>
+       mono --debug program.exe
+       </b>
 
-** Letting the JIT dynamically create the symbol file
+       Notice that the program will need to be compiled with the -g
+       flag and that running with --debug will slow down the execution.
 
-       This'll give you a symbol file which is suitable for debugging IL byte
-       code - you won't see your C# source code.
+* Debugging with GDB
 
-       However, this method has the advantage that it works with every assembly,
-       no matter whether it has been compiled with Mono's C# compiler (MCS) or
-       with any other compiler. It's currently the only way to debug
-       <tt>corlib.dll</tt> or any other library which cannot be compiled with
-       our compiler yet.
+       If you use GDB to debug your mono process, you can use the function
+       mono_print_method_from_ip(void *address) to obtain the name of a method
+       given an address.
 
-       All that you need is a dump of the IL bytecode for each assembly (including
-       all assemblies this assembly is referencing). This is done by using the
-       <tt>monodis</tt> utility:
+       For example:
 
        <pre>
-       monodis /home/export/martin/MONO-LINUX/lib/corlib.dll > corlib.il<br>
-       monodis /home/export/martin/MONO-LINUX/lib/System.dll > System.il<br>
-       monodis /home/export/martin/MONO-LINUX/bin/mcs.exe > mcs.il
-       </pre>
+(gdb) where
+#0  ves_icall_System_String_GetHashCode (me=0x80795d0) at string-icalls.c:861
+#1  0x0817f490 in ?? ()
+#2  0x0817f42a in ?? ()
+#3  0x0817f266 in ?? ()
+#4  0x0817f1a5 in ?? ()
+</pre>
 
-       This is normally done automatically, but you can also disable
-       it and create them by hand.  See the <tt>mono</tt> manual page
-       for details.
+       You can now use:
 
-       Make sure that all the .il files have the same name as their corresponding
-       assembly and that they're all created in the current directory.
+<pre>
+(gdb) p mono_print_method_from_ip (0x0817f490)
+IP 0x817f490 at offset 0x28 of method (wrapper managed-to-native) System.String:GetHashCode () (0x817f468 0x817f4a4)
+$1 = void
+(gdb) p mono_print_method_from_ip (0x0817f42a)
+IP 0x817f42a at offset 0x52 of method System.Collections.Hashtable:GetHash (object) (0x817f3d8 0x817f43b)
+$2 = void
+</pre>
 
-       The JIT supports two different debugging file formats:
+       Mono support libraries use a couple of signals internally that
+       confuse gdb, you might want to add this to your .gdbinit file:
 
-       <ul>
-       * STABS: This is a very simple debugging format, but it may be the only one
-       which is supported on your system. It is limited to source files of no more
-       than 65.535 lines and it's type support is also very limited. You should only
-       use this if your debugger doesn't support DWARF 2.
+<pre>
+       handle SIGPWR nostop noprint 
+       handle SIGXCPU nostop noprint 
+</pre>
 
-       To generate STABS output, use the <tt>--debug=stabs</tt> command line argument.
+* Mono Debugger 
 
+       The Mono debugger is written in C# and can debug both managed
+       and unmanaged applications, support for multiple-threaded
+       applications and should be relatively easy to port to new
+       platforms.
 
-       * DWARF 2: The DWARF 2 debugging format is a very powerful debugging format
-       which can handle source files of arbitrary size and has a highly sophisticated
-       type support. It's the recommended format unless you need to use STABS because
-       your debugger doesn't support DWARF 2.
+       Details of the release are available in <a
+       href="http://lists.ximian.com/archives/public/mono-list/2003-January/011415.html">post</a>. 
+       
+       The debugger contains both Gtk# and command line interfaces.
+       The debugging file format used in Dwarf (it's already supported
+       by our class libraries and the Mono C# compiler; To debug C
+       applications, you need a recent GCC, or to pass the -gdwarf-2
+       flag to gcc).
 
-       To generate DWARF 2 output, use the <tt>--debug=dwarf</tt> command line argument.
-       </ul>
+       You can download the releases from <a
+       href="http://primates.ximian.com/~martin/debugger/">Martin Baulig's
+       home page.</a>
 
-       You need to regenerate the symbol file each time the JIT compiled a new
-       method and each time you restart the JIT. You cannot reuse your symbol file
-       if you start the JIT a second file, not even if you're running the same
-       application with the same input data a second time.
 
-       Regenerating the symbol file is done by calling the JIT's
-       <tt>mono_debug_make_symbols ()</tt> function from within your debugger and
-       then reloading the symbol files. This function creates a <tt>filename-dwarf.s</tt>
-       (or <tt>filename-stabs.s</tt>) assembler input file in the current directory and
-       an object file in <tt>/tmp/filename.o</tt> - you need to tell your debugger to
-       add this object file as symbol file.
-
-       If you're using the GNU debugger, this is done like this:
-
-       <pre>
-       call mono_debug_make_symbols ()
-       add-symbol-file /tmp/corlib.o
-       add-symbol-file /tmp/mcs.o
-       add-symbol-file /tmp/Mono.CSharp.Debugger.o
-       </pre>
-
-       You can also write a GDB macro like this:
-
-       <pre>
-       define reload
-         call mono_debug_make_symbols ()
-         add-symbol-file /tmp/corlib.o
-         add-symbol-file /tmp/mcs.o
-         add-symbol-file /tmp/Mono.CSharp.Debugger.o
-       end
-       </pre>
-
-       Then you can just say <tt>reload</tt> to have GDB recreate the symbol file.
-
-       There's also an <a href="jit-debug-sample.html">example debugging session</a> using
-       the GNU debugger.
-
-** Using a symbol file which have been created by the Mono C# compiler
-
-       If you compiled your application with Mono's C# compiler (MCS), you can tell it to
-       create a symbol file which is then processed and rewritten by the JIT engine.
-
-       To do this, you must give MCS the <tt>-g</tt> option:
-
-       <pre>
-       $ mcs -g Foo.cs
-       </pre>
-
-       This creates a <tt>Foo-debug.s</tt> assembler input file.
-
-       To use this in the JIT, you must first copy it to the target machine (the machine
-       where you want to run the JIT to debug your application) and run it through the
-       assembler to produce an object file <tt>Foo-debug.o</tt>. This object file must be
-       in the current directory.
-
-       Then start the JIT in your debugger and give it the <tt>--debug=dwarf-plus</tt> command
-       line argument.
-
-       Each time you call <tt>mono_debug_make_symbols ()</tt> from withing your debugger,
-       the JIT will read this <tt>Foo-debug.o</tt>, fix some machine dependent things like
-       memory addresses etc. in it and write it back to disk.
-
-       If you're using the GNU debugger, you'll want to use a macro like this:
-
-       <pre>
-       define relocate
-         call mono_debug_make_symbols ()
-         add-symbol-file /tmp/corlib.o
-         add-symbol-file mcs-debug.o
-         add-symbol-file Mono.CSharp.Debugger-debug.o
-       end
-       </pre>
-
-       If there is no <tt>assembly-debug.o</tt> file, but an <tt>assembly.il</tt> one, the
-       JIT will fall back to normal DWARF 2 (in the example above, <tt>corlib.dll</tt> was
-       compiled with Microsoft's compiler and the JIT is thus using DWARF to debug it).
-
-       This debugging method only works if you compiled your assembly with MCS, but it'll
-       allow you to actually debug your C# source code :-)
-
-       Here's an <a href="jit-debug-sample2.html">example debugging session</a> using
-       the GNU debugger.
-
-** Breakpoints and single stepping
-
-       The JIT has a <tt>--break</tt> command line argument to insert a breakpoint at the
-       beginning of this method. It takes a <tt>Namespace.Class:Method</tt> argument which
-       is the method. This argument can be given multiple times.
-
-       However, once your application is stopped in GDB you may want to insert a breakpoint
-       the next time the JIT compiles a method. There's a global variable
-       <tt>mono_debug_insert_breakpoint</tt> which you can modify in your debugger.
-
-       If this variable is set to a non-zero value, the JIT's <tt>arch_compile_method</tt>
-       will insert a breakpoint the next time it is called, ie. at the top of the next
-       method it compiles. If this value has a positive value, it acts as a counter and is
-       decremented after inserting the breakpoint - setting it to a negative value will let
-       the JIT insert the breakpoint each time it compiles a new method.
-
-       There's also global variable <tt>mono_debug_last_breakpoint_address</tt> which always
-       contains the address of the last inserted breakpoint. You may manually override this
-       address with a <tt>nop</tt> instruction to delete the breakpoint.
-
-       For instance, I have a GDB macro called <tt>enter</tt> which I use to enter a method
-       rather than stepping over it:
-
-       <pre>
-       define enter
-       set mono_debug_insert_breakpoint = 1
-       continue
-       set *mono_debug_last_breakpoint_address = 0x90
-       relocate
-       frame
-       </pre>
-
-       Btw. speaking of single stepping - you should use your debuggers <tt>next</tt> command,
-       not its <tt>step</tt> command for single stepping unless you compiled the JIT without
-       debugging support. The reason for this is that the JIT creates machine code which contains
-       calls to JIT methods such as <tt>mono_object_new_wrapper</tt> at places where you don't
-       expect them - so unless the JIT is compiled at least without line numbers, your debugger
-       will enter such methods if you use <tt>step</tt> rather than <tt>next</tt>.
 
 
+       
+       
 
+