Hi guys,

after a long day of hacking, there's a cool new toy for you :-)

The JIT engine `mono' now displays source lines and IL offset in
stack traces if you enabled the debugging support.

There are two ways to do this:

1.) Use the "dwarf" / "stabs" debugging format.

    This works for every assembly - no matter whether it has been
    compiled with mcs or csc.

    Just start mono like this:

        mono --debug dwarf <yourapp.exe>

    or

        mono --debug stabs <yourapp.exe>

    Here's a real-life example:

=====
mono --debug dwarf mcs.exe --timestamp -o mcs-mono2.exe -g assign.cs attribute.cs 
driver.cs cs-parser.cs cs-tokenizer.cs tree.cs location.cs cfold.cs class.cs 
codegen.cs const.cs constant.cs decl.cs delegate.cs enum.cs ecore.cs expression.cs 
genericparser.cs interface.cs literal.cs modifiers.cs namespace.cs parameter.cs 
report.cs rootcontext.cs statement.cs support.cs typemanager.cs
Recreating mcs.il from mcs.exe.
Recreating corlib.il from /home/martin/MONO-LINUX/lib/corlib.dll.
[04:162] Loading references
[00:040]    References loaded
Recreating Mono.CSharp.Debugger.il from 
/home/martin/MONO-LINUX/lib/Mono.CSharp.Debugger.dll.
[00:515] Initializing Core Types
[00:003]    Core Types done
[00:000] Resolving tree
[00:064] Populate tree
[01:268] Emitting code
[14:063]    done
[00:000] Closing types
[00:266] Saved output

(process:31654): ** WARNING **: unhandled exception System.NullReferenceException: "A 
null value was found where an object
instance was required"
in (unmanaged) System.Reflection.MonoCMethod:InternalInvoke ()
in [0x00003] (at corlib.il:143483) System.Reflection.MonoCMethod:Invoke 
(System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)
in [0x00035] (at Mono.CSharp.Debugger.il:5458) .DieSubProgram:get_abbrev_id 
(DieCompileUnit,Mono.CSharp.Debugger.ISourceMethod)
in [0x00004] (at Mono.CSharp.Debugger.il:5492) .DieSubProgram:.ctor 
(DieCompileUnit,Mono.CSharp.Debugger.ISourceMethod)
in [0x00007] (at Mono.CSharp.Debugger.il:9305) 
Mono.CSharp.Debugger.MonoSymbolWriter:WriteMethod 
(DieCompileUnit,Mono.CSharp.Debugger.ISourceMethod)
in [0x00031] (at Mono.CSharp.Debugger.il:9398) 
Mono.CSharp.Debugger.MonoSymbolWriter:WriteSource 
(Mono.CSharp.Debugger.DwarfFileWriter,Mono.CSharp.Debugger.ISourceFile)
in [0x00032] (at Mono.CSharp.Debugger.il:9557) 
Mono.CSharp.Debugger.MonoSymbolWriter:CreateDwarfFile (string)
in [0x00031] (at Mono.CSharp.Debugger.il:8792) 
Mono.CSharp.Debugger.MonoSymbolWriter:Close ()
in [0x00011] (at mcs.il:44681) Mono.CSharp.CodeGen:SaveSymbols ()
in [0x00a84] (at mcs.il:10487) Mono.CSharp.Driver:MainDriver (string[])
in [0x00011] (at mcs.il:9278) Mono.CSharp.Driver:Main (string[])
======

    The *.il files are automatically created for you.

2.) If you compiled your assembly with mcs, you can use the "dwarf2-plus" format to get
    the lines in your C# source code.

    You need to compile your app with the -g option like this:

       mcs -g exception.cs

    Then start the JIT like this:

       mono --debug dwarf-plus <yourapp.exe>

    Here's a real-life example:

=====
[martin@einstein work]$ mcs -g exception.cs
MonoDwarfFileWriter [00:029] Emitting compile units
MonoDwarfFileWriter [00:083] Done
MonoDwarfFileWriter [00:036] Done emitting 34 line numbers
MonoDwarfFileWriter [00:012] Done writing abbrev declarations
MonoDwarfFileWriter [00:020] Done writing 82 reloc entries
RESULT: 0
[martin@einstein work]$ mono --debug dwarf-plus exception.exe
Recreating exception.il from exception.exe.
Recreating corlib.il from /home/martin/MONO-LINUX/lib/corlib.dll.
Void DoTest()
EXCEPTION!
System.ArgumentNullException
Argument cannot be nullSystem.ArgumentNullExceptionin [0x0000d] (at corlib.il:6438) 
System.Array:Sort (System.Array)
in [0x00006] (at exception.cs:12) MyException.Test:DoTest ()
in (unmanaged) System.Reflection.MonoMethod:InternalInvoke ()
in [0x00004] (at corlib.il:143099) System.Reflection.MonoMethod:Invoke 
(object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)
in [0x00032] (at exception.cs:33) MyException.MyException:Main (string[])

in [0x0000d] (at corlib.il:6438) System.Array:Sort (System.Array)
in [0x00006] (at exception.cs:12) MyException.Test:DoTest ()
in (unmanaged) System.Reflection.MonoMethod:InternalInvoke ()
in [0x00004] (at corlib.il:143099) System.Reflection.MonoMethod:Invoke 
(object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)
in [0x00032] (at exception.cs:33) MyException.MyException:Main (string[])


(process:32129): ** WARNING **: unhandled exception System.ArgumentNullException: 
"Argument cannot be null"
in [0x0000d] (at corlib.il:6438) System.Array:Sort (System.Array)
in [0x00006] (at exception.cs:12) MyException.Test:DoTest ()
in [0x00068] (at exception.cs:40) MyException.MyException:Main (string[])

RESULT: -1
====

    The C# source code is here:

====
using System;
using System.Reflection;

namespace MyException
{
        public class Test
        {
                public void DoTest ()
                {
                        try {
                                Array.Sort (null);
                        } catch (ArgumentOutOfRangeException) {
                                Console.WriteLine ("CAUGHT!");
                        }
                }
        }

        public class MyException
        {
                public static void Main (string[] args)
                {
                        Type type = typeof (Test);
                        Type[] argtypes = {};

                        MethodInfo method = type.GetMethod ("DoTest", argtypes);

                        Console.WriteLine (method);

                        Test test = new Test ();

                        try {
                                Object retval = method.Invoke (test, null);
                        } catch (Exception e) {
                                Console.WriteLine ("EXCEPTION!");
                                Console.WriteLine (e);
                                Console.WriteLine (e.StackTrace);
                        }

                        test.DoTest ();
                }
        }
}
====

Btw. in the stack traces, addresses in [ ] are IL offsets and addresses in < > are
machine addresses.

-- 
Martin Baulig
[EMAIL PROTECTED]


_______________________________________________
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to