2008-10-20 6 views

Répondre

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

Ce code fonctionne sur n'importe quel thread.

+13

Nouveauté de Mac OS X 10.6, qui n'existait pas lorsque cette question avait été initialement posée. Pour pré-Snow-Leopard, utilisez les fonctions 'backtrace' et' backtrace_symbols'; voir la page de manuel backtrace (3). –

+3

Fonctionne également sur iOS. –

+5

Seulement sur iOS 4.0 et au-dessus. – Danra

6

This à peu près vous dit quoi faire.

Essentiellement, vous devez configurer les applications de gestion des exceptions pour ouvrir une session, quelque chose comme:

#import <ExceptionHandling/NSExceptionHandler.h> 

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

Notez bien que cela ne fonctionne que dans un gestionnaire d'exception enregistrée (non, par exemple, dans un bloc de @catch) –

9

Cocoa enregistre déjà la trace de la pile sur les exceptions non interceptées de la console, bien qu'il ne s'agisse que d'adresses mémoire brutes. Si vous voulez des informations symboliques dans la console, il y a quelques sample code d'Apple.

Si vous souhaitez générer une trace de pile à un point arbitraire de votre code (et que vous êtes sur Leopard), reportez-vous à la page de manuel backtrace. Avant Leopard, vous deviez creuser la pile d'appels elle-même.

+6

Apparemment disponible dans iOS 4 mais pas 3.2. Voici ce que je, sans vergogne copié à partir de la page de manuel Backtrace: #include ... void * callstack [128]; int i, frames = backtrace (callstack, 128); char ** strs = backtrace_symbols (callstack, frames); pour (i = 0; i mharper

+0

Appelé dans HandleException, il écrit lui-même la trace de la fonction de gestionnaire, tandis que [NSException callStackSymbols] affiche la pile de l'emplacement où l'exception a été levée. Mais si vous remplacez "backtrace (...)" par: "NSArray arr = [ex callStackReturnAddresses]; int frames = arr.count; pour (i = 0; i Tertium

33

travail na pas de réponse de n13 tout à fait - je l'ai modifié légèrement pour arriver à ce

#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; 
    } 
} 
+2

Bonne approche! Je cherchais depuis longtemps ce type de code. – NightFury

+1

Gah ... Apple devrait en faire un standard au moins lors du développement d'une application. Un tas d'adresses de mémoire est ... archaïque – Russ

+0

J'ai mis vos améliorations dans ma réponse; Je l'ai fait avant ARC. Merci. – n13

Questions connexes