如何将堆栈跟踪打印到控制台/登录 Cocoa?
Posted
技术标签:
【中文标题】如何将堆栈跟踪打印到控制台/登录 Cocoa?【英文标题】:How do you print out a stack trace to the console/log in Cocoa? 【发布时间】:2010-09-18 05:20:19 【问题描述】:我想在某些时间点记录调用跟踪,例如失败的断言或未捕获的异常。
【问题讨论】:
【参考方案1】:如果你想把它作为 NSString.
[NSThread callStackSymbols].description
【讨论】:
【参考方案2】:此代码适用于任何线程:
NSLog(@"%@", NSThread.callStackSymbols);
返回一个包含调用堆栈符号的数组。每个元素都是一个
NSString
对象,其值的格式由backtrace_symbols()
函数确定。
【讨论】:
Mac OS X 10.6 中的新功能,最初提出此问题时不存在。对于 pre-Snow-Leopard,使用backtrace
和 backtrace_symbols
函数;请参阅 backtrace(3) 手册页。
仅适用于 ios 4.0 及更高版本。
谢谢!有没有办法让它只打印堆栈跟踪,比如向下 6 级而不是一路?
9000,直接使用backtrace/backtrace_symbols
【参考方案3】:
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;
【讨论】:
Gah...Apple 至少在开发应用程序时应该将此作为标准。一堆内存地址是......过时的 我把你的改进放在我的回答中;我在 ARC 之前做过这个。谢谢。 这不适用于所有情况。如果您想捕获所有未捕获的异常,这是一种更好的方法:codereview.stackexchange.com/questions/56162/…(该问题中的代码有点过于复杂,但它不仅仅是简单地记录调用堆栈符号。) 如果你也想要实际的异常,可以添加NSLog(@"[Error] - %@ %@", exception.name, exception.reason);
【参考方案4】:
Cocoa 已经在控制台记录了未捕获异常的堆栈跟踪,尽管它们只是原始内存地址。如果您想要控制台中的符号信息,Apple 提供了一些 sample code。
如果您想在代码中的任意点生成堆栈跟踪(并且您在 Leopard 上),请参阅 backtrace 手册页。在 Leopard 之前,您实际上必须挖掘调用堆栈本身。
【讨论】:
显然在 iOS 4 中可用,但在 3.2 中不可用。这是我使用的,从回溯手册页无耻地复制:#includeThis 几乎可以告诉你该怎么做。
基本上你需要设置应用程序异常处理来记录,比如:
#import <ExceptionHandling/NSExceptionHandler.h>
[[NSExceptionHandler defaultExceptionHandler]
setExceptionHandlingMask: NSLogUncaughtExceptionMask |
NSLogUncaughtSystemExceptionMask |
NSLogUncaughtRuntimeErrorMask]
【讨论】:
请注意,尽管这仅适用于已注册的异常处理程序(而不是,例如,在 @catch 块中)【参考方案6】:以这种方式快速打印:
print("stack trace:\(Thread.callStackSymbols)")
【讨论】:
【参考方案7】:对于异常,您可以使用异常的 userInfo 字典的 NSStackTraceKey 成员来执行此操作。请参阅 Apple 网站上的 Controlling a Program's Response to Exceptions。
【讨论】:
如何在 Swift 中使用?以上是关于如何将堆栈跟踪打印到控制台/登录 Cocoa?的主要内容,如果未能解决你的问题,请参考以下文章