例外なく.NETで現在のスタックトレースを印刷する方法


349

通常のC#コードがあります。例外はない。デバッグのために、現在のスタックトレースをプログラムでログに記録したいと思います。例:

public void executeMethod() 
{
    logStackTrace();
    method();
}

回答:


399

System.Diagnostics名前空間を見てください。そこにはたくさんのグッズがあります!

System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();

これは、内部で何が行われているのかを知るために少し試してみるのに本当に良いです。

目的を達成できる可能性のあるロギングソリューション(NLog、log4net、Microsoftのパターンやプラクティスエンタープライズライブラリなど)を確認することをお勧めします。頑張って!


74
覚えておいてStackTraceある遅い犬ので控えめにそれを使用します- 。
ジョナサンディキンソン

214

代わりの方法は、スタックトレースの文字列表現を返すSystem.Environment.StackTraceSystem.Diagnostics.StackTraceを使用することです。

別の有用なオプションが使用することです$CALLERし、$CALLSTACK Visual Studioでのデバッグ変数を、このアプリケーションを再構築することなく、実行時に有効にすることができるからです。


6
Environment.StackTrace新しいのはのインスタンスですStackTrace
ダニエル

9
@ダニエル:はい、しかし、System.Environment.StackTraceその情報にアクセスするためのより便利な方法かもしれません。
larsmoa

6
@AndreiRinea:実際には、次を使用して行番号にアクセスできますSystem.Diagnostics.StackTrace
。msdn.microsoft.com/ en

5
Environment.StackTraceいつもはじまるのは面倒じゃないat System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace()ですか?誰かが探している時点では、それは現在のスタックトレースの一部ではありません。
ロリー

7
@Rory、コンストラクタStackTrace(int skipFrames、bool fNeedFileInfo)を見て、開始フレームをスキップできます。ILSpyでメソッドをipenすると、それが何をするかを見ることができます
Walter Vehoeven

39

これを行うには2つの方法があります。System.Diagnostics.StackTrace()あなたの現在のスレッドのスタックトレースを与えます。Threadインスタンスへの参照がある場合、のオーバーロードされたバージョンを介してそのインスタンスのスタックトレースを取得できますStackTrace()

スタックオーバーフローの質問を確認することもできます。現在のスレッド以外のスタックトレースを取得するには


16

コードを変更せずにVisual Studioデバッガーでこれを行うこともできます。

  1. スタックトレースを表示するブレークポイントを作成します。
  2. VS2015でブレークポイントを右クリックし、[アクション...]を選択します。VS2010では、[ヒットしたとき...]を選択し、[メッセージの印刷]を有効にします。
  3. 「実行を続行」が選択されていることを確認してください。
  4. 印刷したいテキストを入力します。
  5. スタックトレースを表示する場所に$ CALLSTACKを追加します。
  6. デバッガーでプログラムを実行します。

もちろん、これは別のマシンでコードを実行している場合には役に立ちませんが、リリースコードに影響を与えたり、プログラムを再起動する必要がなくても、スタックトレースを自動的に吐き出すことができると非常に便利です。


7
スタックトレースを表示する必要があり、ブレークポイントですでにVSデバッガーにいる場合は、[デバッグ]-> [ウィンドウ]-> [スタックを呼び出す]に移動します。
khargoosh

5
はい。ただし、この方法で行う場合、スタックトレースを表示するためにプログラムを停止する必要はありません。
Hank Schultz

7
Console.WriteLine(
    new System.Diagnostics.StackTrace().ToString()
    );

出力は次のようになります。

YourNamespace.Program.executeMethod(String msg)で

YourNamespace.Program.Main(String [] args)

メソッドに置き換えConsole.WriteLineますLog。実際、.ToString()Console.WriteLineケースは受け入れるので、 必要はありませんobject。しかし、Log(string msg)メソッドにはそれが必要な場合があります。


-2
   private void ExceptionTest()
    {
        try
        {
            int j = 0;
            int i = 5;
            i = 1 / j;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            var stList = ex.StackTrace.ToString().Split('\\');
            Console.WriteLine("Exception occurred at " + stList[stList.Count() - 1]);
        }
    }

私のために働くようです


3
これは明らかな例外を生成するだけです。どうして?それ自体で例外を発生させる欠陥ではなく、単に明示的に例外をインスタンス化しないのはなぜですか?実際の例外に到達するために必要な追加のキャッチロジックの利点は何ですか?それでも、スタックトレースを取得する方法に関する実際の投稿された質問を例外なく無視しています(タイトルを読んでください)。
18:06の

それは有効な答えですが、神の恐ろしい解決策です。誰も使用すべきではありません... @Jeffどこに行っても、提案されている他の回答のように降下コードに置き換えてください。
Tomer W
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.