예외없이 .NET에서 현재 스택 추적을 인쇄하는 방법은 무엇입니까?


348

일반 C # 코드가 있습니다. 나는 예외가 없다 . 디버깅 목적으로 현재 스택 추적을 프로그래밍 방식으로 기록하고 싶습니다. 예:

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

답변:


399

System.Diagnostics네임 스페이스를 살펴보십시오 . 거기에 많은 케이크!

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

이것은 후드 아래에서 일어나는 일을 배우기 위해 주위를 찌르는 것이 정말 좋습니다.

NLog, log4net 또는 Microsoft 패턴 및 사례 엔터프라이즈 라이브러리와 같은 로깅 솔루션을 살펴보고 목적을 달성하고 일부를 달성하는 것이 좋습니다. 행운을 빌어 친구!


74
개가 느리다StackTrace 는 것을 명심하십시오 .
Jonathan Dickinson

213

다른 대안 은 스택 추적의 문자열 표현을 반환하는 System.Environment.StackTraceSystem.Diagnostics.StackTrace 를 사용 하는 것입니다.

또 다른 유용한 옵션은 Visual Studio에서$CALLER$CALLSTACK 디버깅 변수 를 사용하는 것 입니다. 응용 프로그램을 다시 빌드하지 않고도 런타임을 활성화 할 수 있기 때문입니다.


6
Environment.StackTrace그냥 new의 인스턴스입니다 StackTrace.
다니엘

9
@Daniel : 예.하지만 System.Environment.StackTrace그 정보에보다 편리하게 액세스 할 수 있습니다.
larsmoa 2019

6
@AndreiRinea : 사실, 난 당신이 사용하는 줄 번호에 액세스 할 수 있습니다 보라 System.Diagnostics.StackTrace- 볼 msdn.microsoft.com/en-us/library/...을
larsmoa

5
Environment.StackTrace항상 시작하는 것이 짜증나 지 at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace()않습니까? 그것은 누군가가 찾고있는 시점에서 현재 스택 추적의 일부가 아닙니다.
Rory

7
@Rory, 생성자 StackTrace (int skipFrames, bool fNeedFileInfo)를 살펴보면 시작 프레임을 건너 뛸 수 있습니다. ILSpy의 방법을 IPEN 당신은 무엇을 볼 수 있습니다
월터 Vehoeven


16

코드를 수정하지 않고 Visual Studio 디버거에서이 작업을 수행 할 수도 있습니다.

  1. 스택 추적을 보려는 중단 점을 작성하십시오.
  2. 중단 점을 마우스 오른쪽 단추로 클릭하고 VS2015에서 "조치 ..."를 선택하십시오. VS2010에서 "히트시 ..."를 선택한 다음 "메시지 인쇄"를 활성화하십시오.
  3. "계속 실행"이 선택되어 있는지 확인하십시오.
  4. 인쇄 할 텍스트를 입력하십시오.
  5. 스택 추적을보고 싶은 곳에 $ CALLSTACK을 추가하십시오.
  6. 디버거에서 프로그램을 실행하십시오.

물론 다른 컴퓨터에서 코드를 실행하는 경우에는 도움이되지 않지만 릴리스 코드에 영향을주지 않거나 프로그램을 다시 시작할 필요없이 스택 추적을 자동으로 추출 할 수 있으면 매우 편리합니다.


7
스택 추적을보고 중단 점에서 이미 VS 디버거에있는 경우 디버그-> Windows-> 콜 스택으로 이동하십시오.
khargoosh

5
예, 그러나 이렇게하면 스택 추적을보기 위해 프로그램을 중지 할 필요가 없습니다.
행크 슐츠

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
이것은 명백한 예외를 생성하고 있습니다. 왜? 예외를 발생시키는 결함보다는 단순히 명시 적으로 예외를 인스턴스화하지 않는 이유는 무엇입니까? 실제 예외에 도달하는 데 필요한 추가 catch 논리의 이점은 무엇입니까? 그럼에도 불구하고 예외없이 스택 추적을 얻는 방법에 대한 실제 게시 된 질문은 여전히 ​​무시 하고 있습니다 (제목 읽기).
Flater

그것은 정답이지만 신이 끔찍한 해결책입니다. 누구도 IT를 사용하지 말아야합니다 ... @Jeff 어디에서든지 제안 된 다른 답변과 같이 하강 코드로 대체하십시오.
Tomer W
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.