Como faço para depurar um acidente quando executo meu aplicativo coletado de lixo em Rosetta?
-
25-09-2019 - |
Pergunta
Eu tenho um aplicativo universal que tem como alvo 10.5 e que usa a coleta de lixo. Estou construindo para PPC, i386 e x86_64.
Não tenho acesso a uma máquina PowerPC física, por isso estou tentando usar o Rosetta para confirmar que a parte do PowerPC do aplicativo funciona corretamente.
No entanto, assim que o aplicativo for lançado em Rosetta, ele trava imediatamente com o seguinte log de acidente:
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
Eu usei o Apple Docs em depuração de aplicativos traduzidos e as informações sobre esta página Para anexar o GDB ao aplicativo quando estiver em Rosetta. O aplicativo entra imediatamente no depurador no lançamento:
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)
Não tenho idéia de por onde começar com isso. Parece que o coletor de lixo está falhando muito. Os aplicativos PowerPC coletados com lixo não são suportados em Rosetta? Não consigo ver nenhuma menção a essa limitação nos documentos, se sim.
Alguém tem alguma idéia?
Solução
Agora determinei que os aplicativos PowerPC coletados com lixo não podem ser executados usando o Rosetta. Depois de cavar no Google, encontrei algumas menções sobre isso na lista de discussão de cacau-dev, embora nada de "oficial" da Apple.
Confirmei que mesmo o aplicativo de aplicação de cacau padrão falhará imediatamente se compilado para PPC com coleta de lixo e depois lançado sob Rosetta.
Devo dizer que é extremamente frustrante que não haja menção a essa limitação no Diretrizes de programação binária universal (que discutem Rosetta), o Guia de programação de coleta de lixo ou as notas de lançamento do Appkit ou Fundação Leopard. Também é frustrante que o tempo de execução não gere algum tipo de mensagem de erro útil.
Como o Leopard/Rosetta/PowerPC agora são "Tecnologias Legadas", não imagino que o registro de um bug contra essa omissão seja muito bom, mas espero que essa resposta ajude aqueles que enfrentam o mesmo problema.
Outras dicas
Uma maneira de testá -lo é desativar o coletor de lixo quando o seu aplicativo é iniciado.
[[NSGarbageCollector defaultCollector] disable];
Você vazará como um louco, mas para um teste menor, isso pode funcionar bem. Uma advertência com isso é que você precisa garantir que seja uma das primeiras coisas que acontecem no seu aplicativo. Dentro main
seria um bom lugar, mas se você vincule a estruturas que funcionam em +load
Métodos (ou têm construtores), pode ser necessário fazê -lo na estrutura (ou interpor em uma biblioteca).