How do I debug a crash when I run my garbage-collected app in Rosetta?
I have a Universal app which is targeting 10.5 and which uses garbage collection. I am building for ppc, i386 and x86_64.
I don't have access to a physical PowerPC machine so I am trying to use Rosetta to confirm that the PowerPC portion of the app works correctly.
However, as soon as the app is launched in Rosetta it immediately crashes with the following crash log:
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
I have used the Apple docs on debugging translated apps and the information on this page to attach gdb to 开发者_如何学运维the app when it's running in Rosetta. The app immediately breaks into the debugger upon launch:
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)
I have no idea where to start with this. It looks like the Garbage Collector is failing very badly. Are garbage-collected PowerPC apps not supported in Rosetta? I can't see any mention of this limitation in the docs if so.
Does anyone have any ideas?
I have now determined that garbage-collected PowerPC apps cannot be run using Rosetta. After digging around in Google I found a couple of mentions about this on the Cocoa-Dev mailing list, although nothing "official" from Apple.
I have confirmed that even the default Cocoa application template app will crash immediately if compiled for ppc with garbage collection and then launched under Rosetta.
I must say it's extremely frustrating that there is no mention of this limitation in either the Universal Binary Programming Guidelines (which discuss Rosetta), the Garbage Collection Programming Guide or the Leopard AppKit or Foundation release notes. It's also frustrating that the runtime doesn't generate some sort of useful error message.
As Leopard/Rosetta/PowerPC are now "legacy technologies" I don't imagine filing a bug against this omission will do much good, but hopefully this answer will help those who come up against the same issue.
One way you can test it is to disable the garbage collector when your application starts.
[[NSGarbageCollector defaultCollector] disable];
You'll leak like crazy, but for a minor test this could work okay. One caveat with this is that you need to make sure that it's one of the first things that happens in your app. In main
would be a good place, but if you link to frameworks that do work in +load
methods (or have constructors), you may need to do it in the framework (or interpose a library instead).
精彩评论