如何将堆栈跟踪打印到Cocoa中的控制台/日志?

rob*_*bor 290 cocoa objective-c

我想在某些点记录调用跟踪,例如失败的断言或未捕获的异常.

smo*_*ris 538

 NSLog(@"%@",[NSThread callStackSymbols]);
Run Code Online (Sandbox Code Playgroud)

此代码适用于任何线程.

  • Mac OS X 10.6中的新功能,在最初询问此问题时不存在.对于Snow-Leopard之前,使用`backtrace`和`backtrace_symbols`函数; 请参阅backtrace(3)联机帮助页. (13认同)
  • 仅适用于iOS 4.0及更高版本. (6认同)
  • 也适用于iOS. (3认同)
  • @sudo这是一个数组,所以只需定义范围 `[NSThread.callStackSymbols subarrayWithRange:NSMakeRange(0, MIN(6, NSThread.callStackSymbols.count))];` (3认同)

Zay*_*ige 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Gah ...... Apple应该至少在开发应用程序时将其作为标准.一堆内存地址是......过时的 (4认同)

vt.*_*vt. 9

Cocoa已经将未捕获的异常的堆栈跟踪记录到控制台,尽管它们只是原始内存地址.如果您想在控制台中获得符号信息,那么Apple会提供一些示例代码.

如果要在代码中的任意点生成堆栈跟踪(并且您在Leopard上),请参阅backtrace手册页.在Leopard之前,你实际上不得不深入挖掘调用堆栈本身.

  • 显然可以在iOS 4中使用,但不能在3.2中使用.这是我使用的,从backtrace手册页无耻地复制:#include <execinfo.h> ... void*callstack [128]; int i,frames = backtrace(callstack,128); char**strs = backtrace_symbols(callstack,frames); for(i = 0; i <frames; ++ i){printf("%s \n",strs [i]); } free(strs); (6认同)

Max*_*art 6

几乎告诉你该怎么做.

基本上,您需要设置应用程序异常处理以进行记录,例如:

#import <ExceptionHandling/NSExceptionHandler.h>

[[NSExceptionHandler defaultExceptionHandler] 
                  setExceptionHandlingMask: NSLogUncaughtExceptionMask | 
                                            NSLogUncaughtSystemExceptionMask | 
                                            NSLogUncaughtRuntimeErrorMask]
Run Code Online (Sandbox Code Playgroud)