A ideia por trás da correção
Vamos lembrar o que realmente dispara o deadlock. É necessário que três tempestades atinjam a camada de depuração ao mesmo tempo, exatamente no momento do anexo:
- CLASS_PREPARE — milhares de classes carregando todas ao mesmo tempo;
- THREAD_END / THREAD_START — centenas de threads curtas-vidas;
- Pressão do GC — alocação pesada durante o início.
Deixe esses três sinais se sobrepor na janela de anexação, e a runtime cai diretamente no estreito ponto entre ObjectTagTable/commonRef e processamento de referências frágeis do sistema.
Há uma segunda face mais prática também. O JDWP é um protocolo síncrono: para cada um desses eventos, a runtime aguarda uma resposta da camada de depuração. Em uma carga em massa (na ordem de 20.000 classes em 25 segundos) você acumula uma avalanche de +40.000 eventos, o binder simplesmente não consegue acompanhar, a fila infla — e o thread principal para completamente. Mesmo onde nunca chega a um deadlock completo, isso sozinho é suficiente para um ANR. Então o problema é realmente duplo: um deadlock estrutural dentro do ART e uma simples superação de um canal síncrono.
A correção adequada no lado AOSP tem que romper o ciclo de bloqueio em si — por exemplo, adiando a entrega do evento livre-JVMTI até depois da seção frágil do sistema fechar. Mas isso é internos da runtime; não podemos alcançar lá a partir do código da aplicação.
O que podemos fazer é abordá-lo de outro lado e remover a pressão. Se o ART parar de notificar a camada JDWP sobre inícios e mortes de threads (e, se você quiser, preparações de classe também), não há avalanche — e sem avalanche significa que a janela do deadlock nunca abre. A lógica da aplicação não poderia se importar menos: esses eventos existem puramente para o próprio livro-razão telemétrico do depurador; eles têm zero efeito sobre como seu código funciona.
Tecnicamente toda a tarefa se resume a uma coisa: interceptar um punhado de métodos internos art::RuntimeCallbacks e trocar por nops. A ferramenta para o trabalho — um hook inline em símbolos nativos libart.so.

