现在,当我在 Xcode 中触发我的一个断言时,我会收到断言消息,以及堆栈的转储,其中充满了对我来说意义不大的数字。
为了跟踪调用堆栈,我需要调试应用程序,并将其运行到断言发生的位置,并希望它再次断言。对于 100% 可重现的错误,这不是什么大问题,但仍然是浪费时间。
如果每次命中断言时我都得到一个调用堆栈跟踪会好得多。
您如何定义将在 Xcode 中转储调用堆栈跟踪的断言宏?
现在,当我在 Xcode 中触发我的一个断言时,我会收到断言消息,以及堆栈的转储,其中充满了对我来说意义不大的数字。
为了跟踪调用堆栈,我需要调试应用程序,并将其运行到断言发生的位置,并希望它再次断言。对于 100% 可重现的错误,这不是什么大问题,但仍然是浪费时间。
如果每次命中断言时我都得到一个调用堆栈跟踪会好得多。
您如何定义将在 Xcode 中转储调用堆栈跟踪的断言宏?
NSThread
有一个被调用的类方法callStackSymbols
(并且NSException
有一个同名的实例方法)。抱歉,我不经常使用异常,也不经常使用断言(不为这两个事实感到自豪),所以我不确定断言宏应该做什么。
#define AssertWithStackSymbols(x) \
do { \
if (!(x)) { \
NSLog (@"%s failed assertion\n%@", #x, [NSThread callStackSymbols]); \
abort(); \
} \
} while(0)
或者,正如 KennyTM 亲切指出的那样,您可以使用backtrace_symbols
. 甚至还有一种将符号直接输出到文件描述符的方法,backtrace_symbols_fd
.
#define AssertWithStackSymbols(x) \
do { \
if (!(x)) { \
void *stack[128]; \
int count; \
fputs (#x " failed assertion.\n", stderr); \
count = backtrace (stack, sizeof stack / sizeof (void *)); \
backtrace_symbols_fd (stack, count, STDERR_FILENO); \
} \
while (0)
在 iOS 4.x 上,您可以使用 [NSThread callStackSymbols] 。