Bagaimana cara mencetak Stack Trace saat ini di .NET tanpa terkecuali?

350

Saya memiliki kode C # biasa. Saya tidak punya pengecualian . Saya ingin secara program mencatat jejak stack saat ini untuk tujuan debugging. Contoh:

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

Jawaban:

400

Lihatlah System.Diagnosticsnamespace. Banyak barang di sana!

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

Ini benar-benar baik untuk melihat-lihat untuk mengetahui apa yang terjadi di bawah tenda.

Saya sarankan Anda melihat-lihat solusi logging (seperti NLog, log4net atau pola dan praktik Microsoft Library Enterprise) yang dapat mencapai tujuan Anda dan kemudian beberapa. Semoga beruntung kawan!

Tempat menyimpan bahan makanan
sumber
74
Ingatlah bahwa itu StackTraceadalah anjing yang lambat - jadi gunakanlah dengan hemat.
Jonathan Dickinson
214

Alternatif untuk System.Diagnostics.StackTracemenggunakan System.Environment.StackTrace yang mengembalikan representasi string dari stacktrace.

Opsi lain yang bermanfaat adalah menggunakan variabel$CALLER dan $CALLSTACK debugging di Visual Studio karena ini dapat diaktifkan waktu berjalan tanpa membangun kembali aplikasi.

larsmoa
sumber
6
Environment.StackTracebaru saja contoh StackTrace.
Daniel
9
@Aniel: Ya, tetapi System.Environment.StackTracemungkin cara yang lebih nyaman untuk mengakses informasi itu.
larsmoa
6
@AndreiRinea: Sebenarnya, saya percaya Anda dapat mengakses nomor saluran menggunakan System.Diagnostics.StackTrace- lihat msdn.microsoft.com/en-us/library/…
larsmoa
5
Bukankah itu menjengkelkan yang Environment.StackTraceselalu dimulai dengan at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace()? Itu bukan bagian dari jejak stack saat ini karena pada titik seseorang mencarinya.
Rory
7
@Rory, lihat konstruktor StackTrace (int skipFrames, bool fNeedFileInfo), Anda dapat melewati bingkai awal. ipen metode dalam ILSpy dan Anda dapat melihat apa yang dilakukannya
Walter Vehoeven
39

Ada dua cara untuk melakukan ini. Ini System.Diagnostics.StackTrace()akan memberi Anda jejak tumpukan untuk utas saat ini. Jika Anda memiliki referensi ke sebuah Threadinstance, Anda bisa mendapatkan jejak stack untuk itu melalui versi overload StackTrace().

Anda mungkin juga ingin memeriksa pertanyaan Stack Overflow. Bagaimana cara mendapatkan stacktrace tidak lancar? .

Brian Rasmussen
sumber
16

Anda juga dapat melakukan ini di debugger Visual Studio tanpa mengubah kode.

  1. Buat breakpoint di mana Anda ingin melihat jejak tumpukan.
  2. Klik kanan breakpoint dan pilih "Tindakan ..." di VS2015. Di VS2010, pilih "When Hit ...", lalu aktifkan "Print a message".
  3. Pastikan "Lanjutkan eksekusi" dipilih.
  4. Ketikkan beberapa teks yang ingin Anda cetak.
  5. Tambahkan $ CALLSTACK di mana pun Anda ingin melihat jejak tumpukan.
  6. Jalankan program di debugger.

Tentu saja, ini tidak membantu jika Anda menjalankan kode pada mesin yang berbeda, tetapi bisa sangat berguna untuk dapat memuntahkan jejak stack secara otomatis tanpa mempengaruhi kode rilis atau bahkan tanpa perlu me-restart program.

Hank Schultz
sumber
7
Jika Anda ingin melihat jejak stack dan Anda sudah berada di VS debugger di breakpoint, cukup buka Debug-> Windows-> Call Stack.
khargoosh
5
Ya, tetapi jika Anda melakukannya dengan cara ini, program tidak harus berhenti agar Anda dapat melihat jejak stack.
Hank Schultz
7
Console.WriteLine(
    new System.Diagnostics.StackTrace().ToString()
    );

Outputnya akan mirip dengan:

di YourNamespace.Program.executeMethod (String msg)

di YourNamespace.Program.Main (String [] args)

Ganti Console.WriteLinedengan Logmetode Anda . Sebenarnya, tidak perlu untuk .ToString()kasus Console.WriteLine saat menerima object. Tetapi Anda mungkin membutuhkannya untuk metode Log (string msg) Anda.

epox
sumber
-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]);
        }
    }

Tampaknya bekerja untuk saya

Jeff Jacobs
sumber
3
Ini hanya menghasilkan pengecualian yang jelas. Mengapa? Mengapa tidak secara eksplisit instantiate pengecualian, daripada cacat yang akan menimbulkan pengecualian dalam dan dari dirinya sendiri? Apa manfaat dari logika tangkap tambahan yang diperlukan untuk mendapatkan pengecualian aktual? Dan meskipun begitu, Anda masih mengabaikan pertanyaan yang diposting aktual tentang cara mendapatkan jejak stack tanpa kecuali (baca judulnya).
Flater
itu jawaban yang valid, tetapi solusi yang mengerikan. TIDAK ADA YANG HARUS MENGGUNAKANNYA ... @ Jeff di mana pun Anda melakukan itu, gantilah dengan kode keturunan seperti jawaban lain yang disarankan.
Tomer W