Как отладить сбой при запуске приложения для сбора мусора в Rosetta?
У меня есть универсальное приложение, которое нацелено на 10.5 и использует сборку мусора. Я строю для PPC, i386 и x86_64.
У меня нет доступа к физическому компьютеру PowerPC, поэтому я пытаюсь использовать Rosetta, чтобы подтвердить, что часть приложения PowerPC работает правильно.
Однако, как только приложение запускается в Rosetta, оно сразу же вылетает со следующим журналом сбоев:
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
Я использовал документы Apple для отладки переведенных приложений и информацию на этой странице, чтобы прикрепить GDB к приложению, когда оно работает в Rosetta. Приложение сразу же запускается в отладчик:
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)
Я понятия не имею, с чего начать. Похоже, сборщик мусора очень сильно выходит из строя. Не поддерживаются ли в Rosetta приложения PowerPC для сбора мусора? Я не вижу никаких упоминаний об этом ограничении в документах, если так.
У кого-нибудь есть какие-либо идеи?
2 ответа
Теперь я определил, что приложения PowerPC для сбора мусора нельзя запускать с помощью Rosetta. Покопавшись в Google, я нашел пару упоминаний об этом в списке рассылки Cocoa-Dev, хотя ничего "официального" от Apple.
Я подтвердил, что даже приложение-шаблон приложения по умолчанию Cocoa сразу же завершит работу, если скомпилируется для ppc со сборкой мусора, а затем будет запущено в Rosetta.
Я должен сказать, что это очень огорчает, что нет упоминания об этом ограничении ни в Универсальных руководящих принципах двоичного программирования (которые обсуждают Rosetta), ни в Руководстве по программированию сборки мусора, ни в Leopard AppKit, ни в примечаниях к выпуску Foundation. Также досадно, что среда выполнения не генерирует какое-то полезное сообщение об ошибке.
Поскольку Leopard/Rosetta/PowerPC в настоящее время являются "устаревшими технологиями", я не думаю, что регистрация ошибки против этого упущения принесет много пользы, но, надеюсь, этот ответ поможет тем, кто сталкивается с той же проблемой.
Один из способов проверить это - отключить сборщик мусора при запуске приложения.
[[NSGarbageCollector defaultCollector] disable];
Вы будете течь как сумасшедший, но для небольшого теста это может работать хорошо. Одно предостережение в том, что вам нужно убедиться, что это одна из первых вещей, которая происходит в вашем приложении. В main
было бы хорошим местом, но если вы ссылаетесь на рамки, которые работают в +load
методы (или иметь конструкторы), вам может потребоваться сделать это в рамках (или вместо этого вставить библиотеку).