The 'Debug.Assert' statement does not work in Mono
-
Debug.Assert is annotated with [ConditionalAttribute("DEBUG")]. This means that all invocations are removed by the compiler unless the DEBUG preprocessor symbol is defined. Try this:
$ dmcs -d:DEBUG LameProg.cs
-
Mono does not show a dialog box like Microsoft's .NET implementation when an assertion is hit. You need to set a TraceListener, e.g.
$ export MONO_TRACE_LISTENER=Console.Error $ mono LameProg.exe
Debug.Assert invocations are typically used in debug builds and removed from release builds. If you want to make sure that a certain condition holds, and this check should be present in release builds, use an if
statement and throw
an exception:
public static void Main(string[] args)
{
int a = 2;
int b = 3;
if (a != b)
{
throw new Exception("Bleh");
}
System.Console.WriteLine("Haha it didn't work");
}
There's another trick: you can add "exit now" behavior through a TraceListener, because Debug.Assert failures trigger a call to Fail() in the trace listener.
You still need to -define:DEBUG (and TRACE?). I personally expect Assert() calls (in DEBUG builds) to stop my program, dump debug info and exit. So, this is how I do it:
In my code I install a custom trace listener to dump stack and add a call to Exit(). And viola! You have an industry standard response to Assert.Fail(). You could also, for example, print timestamps here, etc.
public class DumpStackTraceListener : TraceListener
{
public override void Write( string message )
{
Console.Write( message );
}
public override void WriteLine(string message)
{
Console.WriteLine( message );
}
public override void Fail(string message)
{
Fail( message, String.Empty );
}
public override void Fail(string message1, string message2)
{
if (null == message2)
message2 = String.Empty;
Console.WriteLine( "{0}: {1}", message1, message2 );
Console.WriteLine( "Stack Trace:" );
StackTrace trace = new StackTrace( true );
foreach (StackFrame frame in trace.GetFrames())
{
MethodBase frameClass = frame.GetMethod();
Console.WriteLine( " {2}.{3} {0}:{1}",
frame.GetFileName(),
frame.GetFileLineNumber(),
frameClass.DeclaringType,
frameClass.Name );
}
#if DEBUG
Console.WriteLine( "Exiting because Fail" );
Environment.Exit( 1 );
#endif
}
}
Combine with a call to:
#if DEBUG
Debug.Listeners.Add( new DumpStackTraceListener() );
#endif
And you're good to go.
I believe you need two things: the DEBUG attribute to the compiler, and a 'trace listener' for the runtime. I got it to work with
% export MONO_TRACE_LISTENER=Console.Error
% mcs -define:DEBUG -debug Prog.cs
% mono Prog.exe
That still doesn't exit immediately on assertion failure as I would have expected, but at least it prints something.