Mono - Debug.Assert does not work

前端 未结 3 1853
后悔当初
后悔当初 2021-02-20 02:37

I have this program here:

namespace TodoPlus {
using System.Diagnostics;

    public class LameProg {
        public LameProg() {}
        public static void Mai         


        
相关标签:
3条回答
  • 2021-02-20 02:42

    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.

    0 讨论(0)
  • 2021-02-20 02:46

    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.

    0 讨论(0)
  • 2021-02-20 02:56
    1. 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
      
    2. 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");
    }
    
    0 讨论(0)
提交回复
热议问题