Comment puis-je déboguer un accident lorsque je lance mon application dans le ramasse-miettes Rosetta?
-
25-09-2019 - |
Question
J'ai une application universelle qui vise 10,5 et qui utilise la collecte des ordures. Je construis pour ppc, i386 et x86_64.
Je n'ai pas accès à une machine PowerPC physique, donc je suis en train d'utiliser Rosetta pour confirmer que la partie PowerPC de l'application fonctionne correctement.
Cependant, dès que l'application est lancée en Rosetta, il se bloque immédiatement avec le journal de plantage suivant:
Process: FooApp [91567]
Path: /Users/rob/Development/src/FooApp/build/Release 64-bit/FooApp.app/Contents/MacOS/FooApp
Identifier: com.companyX.FooApp
Version: 0.9 (build d540e05) (2)
Code Type: PPC (Translated)
Parent Process: launchd [708]
Date/Time: 2010-04-09 18:32:23.962 +1000
OS Version: Mac OS X 10.6.3 (10D573)
Report Version: 6
Exception Type: EXC_CRASH (SIGTRAP)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Crashed Thread: 5
...snip non-relevant threads...
Thread 5 Crashed:
0 libSystem.B.dylib 0x8023656a __pthread_kill + 10
1 libSystem.B.dylib 0x80235e17 pthread_kill + 95
2 com.companyX.FooApp 0xb80bfb30 0xb8000000 + 785200
3 com.companyX.FooApp 0xb80c0037 0xb8000000 + 786487
4 com.companyX.FooApp 0xb80dd8e8 0xb8000000 + 907496
5 com.companyX.FooApp 0xb8145397 spin_lock_wrapper + 1791
6 com.companyX.FooApp 0xb801ceb7 0xb8000000 + 118455
Je l'ai utilisé la documentation d'Apple sur le débogage des applications et traduit les informations sur cette page pour attacher gdb à l'application quand il est en cours d'exécution dans Rosetta. L'application se brise immédiatement dans le débogueur lors du lancement:
Program received signal SIGTRAP, Trace/breakpoint trap.
[Switching to thread 15107]
0x9151fdd4 in auto_fatal ()
(gdb) bt
#0 0x9151fdd4 in auto_fatal ()
#1 0x91536d84 in Auto::Thread::get_register_state ()
#2 0x915372f8 in Auto::Thread::scan_other_thread ()
#3 0x91529be4 in Auto::Zone::scan_registered_threads ()
#4 0x91539114 in Auto::MemoryScanner::scan_thread_ranges ()
#5 0x9153b000 in Auto::MemoryScanner::scan ()
#6 0x9153049c in Auto::Zone::collect ()
#7 0x915198f4 in auto_collect_internal ()
#8 0x9151a094 in auto_collection_work ()
#9 0x96687434 in _dispatch_call_block_and_release ()
#10 0x9668912c in _dispatch_queue_drain ()
#11 0x96689350 in _dispatch_queue_invoke ()
#12 0x966895c0 in _dispatch_worker_thread2 ()
#13 0x966896fc in _dispatch_worker_thread ()
#14 0x965a97e8 in _pthread_body ()
(gdb)
Je ne sais pas où commencer avec cela. Il semble que le Garbage Collector échoue très mal. Sont des applications PowerPC-déchets collectés non pris en charge dans Rosetta? Je ne vois aucune mention de cette limitation dans les docs si oui.
Quelqu'un at-il des idées?
La solution
Je suis maintenant déterminé que les applications PowerPC déchets collectés ne peuvent pas être exécutés à l'aide Rosetta. Après avoir creusé autour de Google, j'ai trouvé deux mentions à ce sujet sur la liste de diffusion Cocoa-Dev, bien que rien ne « officiel » d'Apple.
Je confirme que même l'application par défaut de modèle d'application Cocoa se bloque immédiatement si compilé pour ppc avec la collecte des ordures, puis lancé sous Rosetta.
Je dois dire qu'il est extrêmement frustrant qu'il n'y a aucune mention de cette limitation soit dans le Lignes directrices de programmation Universal Binary (qui Rosetta), traitent de la noreferrer Garbage Collection Guide de programmation ou AppKit Leopard ou les notes de version de la Fondation. Il est aussi frustrant que le temps d'exécution ne génère pas une sorte de message d'erreur utile.
Leopard / Rosetta / PowerPC sont maintenant « technologies existantes » Je ne pense pas le dépôt d'un bug contre cette omission fera beaucoup de bien, mais nous espérons que cette réponse aidera ceux qui se heurtent à la même question.
Autres conseils
Une façon vous pouvez le tester est de désactiver le garbage collector lorsque votre application démarre.
[[NSGarbageCollector defaultCollector] disable];
Vous fuyez comme un fou, mais pour un test mineur cela pourrait fonctionner bien. Une mise en garde à ce que vous devez vous assurer qu'il est l'une des premières choses qui se passe dans votre application. En main
serait un bon endroit, mais si vous lien avec les cadres qui fonctionnent dans les méthodes de +load
(ou qui ont des constructeurs), vous devrez peut-être de le faire dans le cadre (ou interposer une bibliothèque à la place).