2010-02-17 10 views
5

Gerade jetzt, wenn einer meiner Behauptungen in Xcode ausgelöst wird, erhalte ich die Assert-Nachricht und einen Dump des Stapels, der voller Zahlen ist, die für mich nicht sehr aussagekräftig sind.Xcode - Call-Stack-Trace auf Assert?

Um eine Spur des Aufruf-Stacks zu erhalten, muss ich die Anwendung debuggen, und es bis zu dem Punkt ausführen, wo die Assert aufgetreten ist, und hoffe, dass es erneut behauptet. Bei Fehlern, die zu 100% reproduzierbar sind, ist dies kein großes Problem, aber immer noch Zeitverschwendung.

Es wäre viel besser, wenn ich jedes Mal eine Call-Stack-Trace bekommen würde, wenn ein Assert getroffen wird.

Wie definieren Sie ein Assert-Makro, das einen Call-Stack-Trace in Xcode ablegt?

Antwort

5

NSThread hat eine Klassenmethode namens callStackSymbols (und NSException hat eine Instanzmethode mit dem gleichen Namen). Entschuldigung, ich verwende keine Ausnahmen und verwende auch nicht regelmäßig Behauptungen (nicht stolz auf beide Tatsachen), daher bin ich mir nicht sicher, was das Assertion-Makro tun sollte.

#define AssertWithStackSymbols(x) \ 
do { \ 
    if (!(x)) { \ 
     NSLog (@"%s failed assertion\n%@", #x, [NSThread callStackSymbols]); \ 
     abort(); \ 
    } \ 
} while(0) 

Oder, wie KennyTM freundlich darauf hingewiesen, können Sie backtrace_symbols verwenden. Es gibt sogar eine Methode, die die Symbole direkt in einen Dateideskriptor backtrace_symbols_fd ausgibt.

#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) 
+0

Oh, vergessen zu erwähnen: Die Methode 'callStackSymbols' ist nur unter Mac OS X 10.6 verfügbar. – dreamlax

+1

Unter OS X 10.5 und iPhoneOS können Sie 'backtrace_symbols (3)' verwenden. – kennytm

1

Auf iOS 4.x können Sie [NSThread callStackSymbols] so verwenden.