Jak wydrukować bieżące śledzenie stosu w .NET bez wyjątku?


348

Mam zwykły kod C #. Nie mam wyjątków . Chcę programowo rejestrować bieżące dane śledzenia stosu w celu debugowania. Przykład:

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

Odpowiedzi:


399

Spójrz na System.Diagnosticsprzestrzeń nazw. Wiele gadżetów!

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

Naprawdę dobrze jest się wkurzyć, aby dowiedzieć się, co się dzieje pod maską.

Polecam przyjrzeć się rozwiązaniom rejestrowania (takim jak NLog, log4net lub wzorce i praktyki Microsoft Enterprise Library), które mogą osiągnąć twoje cele, a następnie niektóre. Powodzenia, kolego!


74
Pamiętaj, że piesStackTrace jest wolny - używaj go oszczędnie.
Jonathan Dickinson

213

Alternatywą System.Diagnostics.StackTracejest użycie System.Environment.StackTrace, która zwraca ciąg reprezentacji stosu.

Inną przydatną opcją jest użycie zmiennych$CALLER i $CALLSTACK debugowanie w Visual Studio, ponieważ można to włączyć w czasie wykonywania bez przebudowywania aplikacji.


6
Environment.StackTracewłaśnie pojawiło się nowe wystąpienie StackTrace.
Daniel

9
@Daniel: Tak, ale System.Environment.StackTracemoże być wygodniejszym sposobem uzyskiwania dostępu do tych informacji.
larsmoa

6
@AndreiRinea: Właściwie wierzę, że możesz uzyskać dostęp do numerów linii za pomocą System.Diagnostics.StackTrace- patrz msdn.microsoft.com/en-us/library/…
larsmoa

5
Czy to nie denerwujące, że Environment.StackTracezawsze zaczyna się od at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace()? To nie jest część aktualnego śladu stosu w momencie, gdy ktoś go szuka.
Rory,

7
@Rory, spójrz na konstruktor StackTrace (int skipFrames, bool fNeedFileInfo), możesz pominąć ramkę początkową. ipen metodę w ILSpy i można zobaczyć, co robi
Walter Vehoeven


16

Można to również zrobić w debugerze programu Visual Studio bez modyfikowania kodu.

  1. Utwórz punkt przerwania, w którym chcesz zobaczyć ślad stosu.
  2. Kliknij punkt przerwania prawym przyciskiem myszy i wybierz „Działania ...” w VS2015. W VS2010 wybierz „Po trafieniu ...”, a następnie włącz „Wydrukuj wiadomość”.
  3. Upewnij się, że wybrano „Kontynuuj wykonywanie”.
  4. Wpisz tekst, który chcesz wydrukować.
  5. Dodaj $ CALLSTACK wszędzie tam, gdzie chcesz zobaczyć ślad stosu.
  6. Uruchom program w debugerze.

Oczywiście nie pomaga to, jeśli uruchamiasz kod na innym komputerze, ale może być całkiem przydatne, aby móc wypluć ślad stosu automatycznie bez wpływu na kod wersji lub nawet bez konieczności ponownego uruchamiania programu.


7
Jeśli chcesz zobaczyć ślad stosu i jesteś już w debuggerze VS w punkcie przerwania, po prostu przejdź do Debuguj-> Windows-> Stos wywołań.
khargoosh

5
Tak, ale jeśli zrobisz to w ten sposób, program nie musi się zatrzymywać, aby zobaczyć ślad stosu.
Hank Schultz

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

Dane wyjściowe będą podobne do:

w YourNamespace.Program.executeMethod (ciąg msg)

at YourNamespace.Program.Main (Argumenty String [])

Zastąp Console.WriteLineswoją Logmetodą. W rzeczywistości nie ma potrzeby stosowania .ToString()konsoli Console.WriteLine, ponieważ akceptuje object. Ale może być to potrzebne do metody 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]);
        }
    }

Wydaje się dla mnie pracować


3
To tylko generuje oczywisty wyjątek. Dlaczego? Dlaczego nie po prostu jawnie utworzyć wyjątek, zamiast wady, która sama w sobie spowoduje wyjątek? Jaka jest korzyść z dodatkowej logiki połowu wymaganej do uzyskania faktycznego wyjątku? I nawet wtedy nadal ignorujesz opublikowane pytanie, w jaki sposób uzyskać ślad stosu bez żadnego wyjątku (przeczytaj tytuł).
Flater

to ważna odpowiedź, ale okropne rozwiązanie. Nikt nie powinien jej używać ... @Jeff, gdziekolwiek to zrobiłeś, zastąp go kodem zejścia, tak jak inne sugerowane odpowiedzi.
Tomer W
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.