System.Diagnostics.Debug.Assert в консольном приложении. Имена файлов и номера строк в дампе стековой трассировки выглядят как <hex>: 0 - PullRequest
0 голосов
/ 17 октября 2019

Я хочу использовать простое утверждение, которое приведет к фатальному исходу и сбросит трассировку стека. Я пытаюсь использовать System.Diagnostics.Debug.Assert для этого:

Я делаю это в режиме отладки:

using System;
using System.Diagnostics;

namespace Bar {
    class MainClass {
        public static void DoBar() {
            Debug.Assert(false, "got false");
        }

        public static void Main(string[] args) {
            DoBar();
        }
    }
}

, но он печатает что-то вроде этого:

Fail: got false
  at System.Diagnostics.DefaultTraceListener.Fail (System.String message, System.String detailMessage) [0x0001d] in <23340a11bb41423aa895298bf881ed68>:0 
  at System.Diagnostics.TraceListener.Fail (System.String message) [0x00000] in <23340a11bb41423aa895298bf881ed68>:0 
  at System.Diagnostics.DefaultTraceListener.Fail (System.String message) [0x00000] in <23340a11bb41423aa895298bf881ed68>:0 
  at System.Diagnostics.TraceInternal.Fail (System.String message) [0x00030] in <23340a11bb41423aa895298bf881ed68>:0 
  at System.Diagnostics.TraceInternal.Assert (System.Boolean condition, System.String message) [0x00004] in <23340a11bb41423aa895298bf881ed68>:0 
  at System.Diagnostics.Debug.Assert (System.Boolean condition, System.String message) [0x00000] in <23340a11bb41423aa895298bf881ed68>:0 
  at Bar.MainClass.DoBar () [0x00001] in <cb880aee1a1f4690a3f434f26546b11a>:0 
  at Bar.MainClass.Main (System.String[] args) [0x00001] in <cb880aee1a1f4690a3f434f26546b11a>:0 

Я не уверен, почему имена файлов в шестнадцатеричном формате, а номера строк всегда равны 0. Что я хочу, это что-то вроде ...

Fail: got false
  at Bar.MyTraceListener.WriteLine (System.String msg) [0x00008] in /Users/foo/Bar/Bar/Program.cs:13 
  at System.Diagnostics.TraceListener.Fail (System.String message, System.String detailMessage) [0x00042] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-06/external/bockbuild/builds/mono-x64/mcs/class/referencesource/System/compmod/system/diagnostics/TraceListener.cs:196 
  at System.Diagnostics.TraceListener.Fail (System.String message) [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-06/external/bockbuild/builds/mono-x64/mcs/class/referencesource/System/compmod/system/diagnostics/TraceListener.cs:180 
  at System.Diagnostics.TraceInternal.Fail (System.String message) [0x00030] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-06/external/bockbuild/builds/mono-x64/mcs/class/referencesource/System/compmod/system/diagnostics/TraceInternal.cs:233 
  at System.Diagnostics.TraceInternal.Assert (System.Boolean condition, System.String message) [0x00004] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-06/external/bockbuild/builds/mono-x64/mcs/class/referencesource/System/compmod/system/diagnostics/TraceInternal.cs:221 
  at System.Diagnostics.Debug.Assert (System.Boolean condition, System.String message) [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-06/external/bockbuild/builds/mono-x64/mcs/class/referencesource/System/compmod/system/diagnostics/Debug.cs:108 
  at Bar.MainClass.DoBar () [0x00001] in /Users/foo/Bar/Bar/Program.cs:19 
  at Bar.MainClass.Main (System.String[] args) [0x00007] in /Users/foo/Bar/Bar/Program.cs:29 

Я посмотрел вокруг, и лучше всегоЯ знаю, что для этого нужно использовать класс StackTrace с ctor, для которого bool fNeedFileInfo имеет значение true:

using System;
using System.Diagnostics;

namespace Bar {
    class MyTraceListener: TraceListener {
        public override void Write(string msg) {
            Console.WriteLine(msg);
            Console.Write(new StackTrace(true));
            Environment.Exit(1);
        }

        public override void WriteLine(string msg) {
            Console.WriteLine(msg);
            Console.WriteLine(new StackTrace(true));
            Environment.Exit(1);
        }
    }

    class MainClass {
        public static void DoBar() {
            Debug.Assert(false, "got false");
        }

        public static void InitDebugListeners() {
            Debug.Listeners.Clear();
            Debug.Listeners.Add(new MyTraceListener());
        }

        public static void Main(string[] args) {
            InitDebugListeners();
            DoBar();
        }
    }
}

Есть ли способ достичь запланированного дампа трассировки стека без необходимости использованиякласс StackTrace? Или это действительно лучший способ сделать это?

Спасибо.

РЕДАКТИРОВАТЬ : О, я только что понял, System.Diagnostics.Debug.Assert не одиниз тех фатальных видов утверждений, как <cassert> в C / C ++. По крайней мере для меня, я поставил Console.WriteLine("foo") после метода, который должен привести к летальному исходу, и он напечатал «foo». Я думаю, это больше похоже на средство ведения журнала, например, на те, которые принимают несколько прослушивателей на одно средство ведения журнала. Если я хочу фатального утверждения, я полагаю, что я могу добавить System.Environment.Exit(1) в один пользовательский прослушиватель

...