Cocoa의 콘솔 / 로그에 스택 추적을 어떻게 인쇄합니까?


293

어설 션 실패 또는 포착되지 않은 예외와 같은 특정 지점에서 통화 추적을 기록하고 싶습니다.

답변:


544
 NSLog(@"%@",[NSThread callStackSymbols]);

이 코드는 모든 스레드에서 작동합니다.


14
Mac OS X 10.6의 새로운 기능으로,이 질문을 처음 받았을 때는 없었습니다. Snow-Leopard 이전의 경우 backtracebacktrace_symbols기능을 사용하십시오 . backtrace (3) 맨 페이지를 참조하십시오.
Peter Hosey

6
iOS 4.0 이상에서만 가능합니다.
Danra

감사! 이 방법으로 스택 추적을 인쇄하는 방법이 있습니까?
sudo

9000, backtrace/backtrace_symbols직접 사용
dymv

34

n13의 대답이 제대로 작동하지 않았습니다.이 문제를 해결하기 위해 약간 수정했습니다.

#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        int retval;
        @try{
            retval = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
        @catch (NSException *exception)
        {
            NSLog(@"Gosh!!! %@", [exception callStackSymbols]);
            @throw;
        }
        return retval;
    }
}

4
가 ... 애플은 최소한 응용 프로그램을 개발하는 동안 이것을 표준으로 만들어야합니다. 메모리 주소의 무리는 ... 구식
Russ

나는 당신의 개선을 내 대답에 넣었습니다. 나는 ARC 전에 이것을했다. 감사.
n13

1
이것은 하지 않는 모든 상황에서 작동합니다. 포착되지 않은 모든 예외를 포착하려는 경우이 방법이 더 좋습니다. codereview.stackexchange.com/questions/56162/… (해당 질문의 코드는 약간 복잡하지만 호출 스택 기호를 기록하는 것 이상을 수행합니다.)
nhgrif

당신은 추가 할 수 있습니다 NSLog(@"[Error] - %@ %@", exception.name, exception.reason);당신이 너무 실제 예외를 원하는 경우
Corentin S.에게

9

Cocoa는 미처리 예외에 대한 스택 추적을 단지 원시 메모리 주소이지만 콘솔에 이미 기록합니다. 콘솔에서 기호 정보를 원한다면 Apple의 샘플 코드가 있습니다.

코드의 임의 지점에서 스택 추적을 생성하려면 (그리고 Leopard를 사용하는 경우) backtrace 매뉴얼 페이지를 참조하십시오. Leopard 이전에는 실제로 호출 스택 자체를 파헤쳐 야했습니다.


6
분명히 iOS 4에서는 사용할 수 있지만 3.2에서는 사용할 수 없습니다. 다음은 백 트레이스 매뉴얼 페이지에서 뻔뻔스럽게 복사 한 것입니다. #include <execinfo.h> ... void * callstack [128]; ini i, 프레임 = 역 추적 (callstack, 128); char ** strs = backtrace_symbols (콜 스택, 프레임); for (i = 0; i <프레임; ++ i) {printf ( "% s \ n", strs [i]); } free (strs);
mharper

HandleException에서 호출되면 핸들러 함수 자체의 추적을 다시 작성하지만 [NSException callStackSymbols]는 예외가 발생한 곳의 스택을 표시합니다. 그러나 "backtrace (...)"를 "NSArray arr = [ex callStackReturnAddresses]; int frames = arr.count; for (i = 0; i <frames; ++ i) callstack [i] = ( void) [((NSNumber *) [arr objectAtIndex : i]) intValue]; " 현재 예외 스택 추적을 얻습니다. 이것이 [NSException callStackSymbols]의 작동 방식입니다. 리턴하는 추적이 동일하며 두 앱 호출 모두 릴리스에서 _mh_execute_header로 대체됩니다.
Tertium

6

이것은 당신에게 무엇을 해야할지 거의 알려줍니다.

기본적으로 다음과 같이 로깅하도록 애플리케이션 예외 처리를 설정해야합니다.

#import <ExceptionHandling/NSExceptionHandler.h>

[[NSExceptionHandler defaultExceptionHandler] 
                  setExceptionHandlingMask: NSLogUncaughtExceptionMask | 
                                            NSLogUncaughtSystemExceptionMask | 
                                            NSLogUncaughtRuntimeErrorMask]

1
그러나 이것은 등록 된 예외 처리기 (예 : @catch 블록이 아닌) 내에서만 작동합니다.
Barry Wark


1

이 방법으로 신속하게 인쇄하십시오.

print("stack trace:\(Thread.callStackSymbols)")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.