Solução de problemas
Meu emulador Android não aparece#
- Execute
adb devices. Se o emulador não estiver listado ali, o EmuLabZip também não consegue vê-lo. Reinicie-o ou executeadb kill-server && adb start-server. - O rodapé do device picker mostra adb unavailable quando o
adbnão é encontrado. Instale as platform tools do Android SDK, ou aponteANDROID_HOMEouEMULABZIP_ADBpara o seu SDK. - Um dispositivo listado como unauthorized está esperando que você aceite o aviso de depuração por USB.
- Uma porta personalizada do servidor ADB precisa ser definida com
ANDROID_ADB_SERVER_PORTouADB_SERVER_SOCKETtambém para o EmuLabZip.
Meu simulador não aparece#
- Apenas simuladores iOS inicializados são listados. Confira com
xcrun simctl list devices booted. - O rodapé mostra simctl unavailable quando as ferramentas de linha de comando do Xcode estão ausentes. Execute
xcode-select --install, ousudo xcode-select -s /Applications/Xcode.appse houver várias versões do Xcode instaladas.
O log está vazio#
- No Android, confira se o
adb logcatimprime linhas. - Olhe o nível mínimo e os filtros; Reset filters aparece quando existem linhas, mas nenhuma corresponde.
- O filtro de app precisa que o app esteja em execução. Inicie o app; o filtro pega o novo id de processo automaticamente.
O log está movimentado demais#
Veja O log unificado é movimentado. No Android, aumente o nível mínimo ou filtre por tag.
Os screenshots falham#
- No Android,
adb exec-out screencap -p > shot.pngprecisa funcionar. Algumas telas seguras (vídeo com DRM, apps de banco) são pretas por design. - No iOS,
xcrun simctl io booted screenshot shot.pngprecisa funcionar.
O Storage diz "only debuggable apps can be browsed"#
O Android só deixa o run-as ler os dados privados de apps depuráveis. Instale um build de debug do seu app, ou teste
as ferramentas com o app de exemplo (tools/sample-app/install.sh). O armazenamento compartilhado funciona para todos
os apps.
Os heap dumps falham no Android#
O am dumpheap precisa de um app depurável, ou de uma imagem de emulador do tipo userdebug/eng (imagens sem Google
Play). O erro mostra o motivo que o Android deu, por exemplo Process not debuggable.
O Performance não mostra a taxa de quadros#
Os quadros só são contados enquanto o app desenha. Interaja com o app; uma tela estática não renderiza nada. No iOS Simulator, as métricas de quadros chegam com os traces do Instruments na Phase 4.
Network: nada aparece#
- Confira se o dispositivo diz sending traffic here. No Android,
adb shell settings get global http_proxydeve imprimir127.0.0.1:<port>. - Alguns apps ignoram o proxy do sistema (os que abrem sockets por conta própria, ou usam HTTP/3). Eles não podem ser capturados.
- Apps que usam muito cache podem nem consultar a rede. Limpe os dados deles ou use uma URL nova.
Network: as requisições HTTPS falham ou aparecem como "Connections"#
O dispositivo não confia no certificado, ou o app fixa o do seu servidor (pinning). Pressione Certificate e siga o que ele diz. Nas imagens Android do Google Play, apenas o Chrome e os apps que permitem certificados de usuário vão confiar nele; veja o certificado. Um banner nomeia os hosts que estão sendo repassados sem decifrar; use Decrypt again depois de corrigir.
Network: o dispositivo ou o Mac continua apontando para o proxy#
Pressione Disconnect, ou execute adb shell settings put global http_proxy :0 no Android. No Mac, abra o EmuLabZip
uma vez: ele restaura as configurações de proxy que salvou se uma execução anterior foi encerrada à força. Caso
contrário, desative os proxies em System Settings › Network › Details › Proxies.
Network: o macOS pede uma senha#
Alterar o proxy do Mac é uma configuração do sistema. O EmuLabZip tenta como você mesmo e só pede direitos de administrador se o macOS recusar.
Network: uma regra não faz nada#
As regras veem requisições decifradas, então o HTTPS precisa do certificado instalado, e um host que o rejeitou é
repassado sem decifrar e não pode ser alterado. A primeira regra ativada que corresponde vence; mova a que você espera
para cima das outras. Um padrão de host corresponde apenas ao host (api.example.com, não
https://api.example.com/).
Network: o HTTP/3 não mostra h3#
O recurso vem desativado por padrão (HTTP/3 → Use HTTP/3 to servers). Um host só é tentado depois que uma de suas respostas disse que oferece HTTP/3, então a primeira requisição é sempre TCP. Uma rede que bloqueia UDP faz o QUIC falhar; o host então fica no TCP por 10 minutos.
Layout: nada para ler no iOS#
O Simulator.app precisa estar aberto naquele dispositivo, e o programa que executa o EmuLabZip precisa ter permissão em
System Settings, Privacy & Security, Accessibility (o app, ou o seu terminal para emulabzip layout). Acorde o
dispositivo se ele mostrar uma tela preta.
Flutter: "Could not find where the Dart VM service listens"#
Apenas os builds de debug e profile têm um, e o app grava o endereço dele no log uma única vez, quando inicia. Inicie o
app de novo, ou informe o endereço da saída do flutter run com --uri. Um build de release não tem VM service.
Flutter: a árvore não tem nomes de arquivo#
O app não foi compilado com --track-widget-creation. O flutter run o adiciona; para flutter build, adicione
--extra-front-end-options=--track-widget-creation.
React Native: "Metro is not running" ou "does not list a runtime"#
Inicie o Metro (npx react-native start) e abra o app em um dispositivo que o alcance (adb reverse tcp:8081 tcp:8081 no Android). O Metro só lista um runtime enquanto o app está conectado a ele, e deixa entrar um depurador por
vez: feche o React Native DevTools e o inspetor do Chrome e tente de novo. Os builds de release não têm Metro nem o
hook do React DevTools.
State: "RN state is empty" ou "no DevTools hook"#
Redux, React Query e contextos são encontrados pelo hook do DevTools do React, que só os builds de desenvolvimento têm.
Em um build de release, registre os stores em globalThis.__EMULABZIP_STORES__ (veja
Estado do React Native). Um store usado sem um Provider do react-redux também precisa ser
registrado.
State: restaurar ou salvar falha no Android#
O app precisa ser depurável (como no Storage). O run-as e o tar rodam no dispositivo: uma imagem de
emulador com o run-as bloqueado não consegue salvar um estado. Uma restauração que diz que o tar foi recusado achou
uma entrada fora da pasta do app; o arquivo não é do EmuLabZip, ou está danificado.
Edit: "the table cannot be changed"#
Uma linha é encontrada por rowid ou pela sua chave primária. Uma view, ou uma tabela sem nenhum dos dois, não tem como
distinguir suas linhas: altere-a com SQL no app. Uma edição que é lida de volta de forma diferente restaura o arquivo
antigo e diz isso.
Devices: um emulador não inicia#
O emulabzip avd boot precisa do emulator do SDK (encontrado a partir de ANDROID_HOME, ANDROID_SDK_ROOT e das
pastas usuais). Execute emulator -avd <name> você mesmo para ver a mensagem dele. Um emulador em execução nunca é
apagado nem excluído: desligue-o antes.
Audit: "the area could not be read"#
O log precisa que o app esteja em execução, para que as linhas dele possam ser distinguidas das do sistema: inicie-o
e use-o, depois audite de novo. O Storage no Android precisa de um app depurável, como no Storage. As
requisições vêm do proxy (inicie-o na view Network, ou passe --har).
Language: "Android changes the language of one app at a time"#
O Android não tem como mudar o idioma de um dispositivo pelo shell, apenas o de um app (cmd locale set-app-locales,
Android 13 e mais recentes). Passe --app, ou escolha o app na barra de ferramentas. O iOS Simulator muda o idioma de
todos os apps, e cada um o assume quando inicia de novo.
Text checks: um label é reportado sem estar cortado#
O text-cut-off é uma heurística: uma única linha cuja caixa foi limitada ao espaço que o seu contêiner (ou a próxima
view na sua linha) deixou, e cujo texto vai até o fim da caixa. Confira a 130% e a 200%; se couber, ignore.
Visual: "the screenshots are not the same size"#
Eles vêm de dispositivos, orientações ou tamanhos de tela diferentes. Compare coisas iguais: o mesmo dispositivo, a mesma
orientação e o mesmo tamanho de tela (control reset-display devolve o de um Android ao normal).
Network: um build do Gradle não consegue baixar sua distribuição#
Não é assunto do EmuLabZip, mas aparece com os apps de demonstração: algumas redes deixam o curl alcançar os servidores
do Gradle enquanto o Java dá timeout. Baixe a distribuição com o curl e coloque-a onde o Gradle espera
(~/.gradle/wrapper/dists/<name>/<hash>/), ou compile com um Gradle que você já tenha.
Layout: o Android diz que o uiautomator não produziu nada#
Algumas janelas o proíbem: telas seguras e alguns players. Vá para outra tela e tente de novo. Se o dispositivo estiver ocupado (uma animação de boot, uma caixa de diálogo de ANR), espere um momento.
Sessions: uma gravação ficou como uma pasta .partial#
A gravação foi encerrada à força antes de conseguir se empacotar. Nada se perde: emulabzip session show run.ezsession.partial a abre. Exclua a pasta, ou mova-a, antes de gravar de novo com o mesmo nome.
Timeline: faltam toques#
Os toques são lidos do dispositivo de entrada do kernel com getevent, então um dedo na janela do emulador ou um evento
enviado pelo console do emulador é visto. O adb shell input tap é injetado mais acima, dentro do Android, e não é. O
iOS não entrega os toques do simulador a nada fora dele, então ali não há nenhum. Grave com --taps.
Timeline: os horários do log são "estimated"#
A gravação foi feita antes do EmuLabZip 0.10, ou o dispositivo não soube informar a hora, então os horários locais do log foram posicionados comparando a primeira linha com o início da gravação. Eles podem estar errados pela diferença entre os dois relógios. Grave de novo para ter horários exatos.
Video: "screenrecord made no video"#
Algumas telas não podem ser gravadas (janelas seguras) e algumas imagens não oferecem suporte ao screenrecord. A
mensagem traz o que a ferramenta imprimiu. No iOS Simulator, o recordVideo precisa que o simulador esteja
inicializado; se não começar em 20 segundos, a mensagem diz o motivo.
Video: o relatório tem um .mp4 separado#
Um clipe de até 20 MB faz parte do arquivo HTML. Um maior é gravado ao lado dele como emulabzip-report.mp4, e o
arquivo se refere a ele por esse nome: mova ou anexe os dois juntos.
Replay: "not in the recording"#
O app pediu algo que a gravação não tem: outro endereço, outra query, um método que não foi usado, ou uma requisição que
falhou quando foi gravada. O proxy responde 504 e a lista em Not recorded (ou no fim do emulabzip net --replay).
Grave de novo com essa requisição, ou adicione --passthrough para deixá-la chegar ao servidor. A correspondência
ignora a ordem dos parâmetros de query e a porta, mas não os valores: um app que adiciona um timestamp ou um id
aleatório a toda requisição sempre vai falhar.
Replay: WebSockets e algumas conexões falham#
Enquanto uma gravação é reproduzida, o que não pode ser respondido a partir de um arquivo HAR é recusado, para que não
alcance a internet: WebSockets, chamadas gRPC, apps que não aceitam o certificado do EmuLabZip e conexões sem TLS que o
proxy não consegue ler. Use --passthrough se elas precisarem funcionar.
Traces: "Perfetto did not record a trace"#
O Perfetto precisa do Android 9 ou mais recente. Se a mensagem citar uma permissão, reinicie o emulador, ou execute
adb shell setprop persist.traced.enable 1 e grave de novo. Uma configuração personalizada com erro de sintaxe é
reportada pelo próprio Perfetto; confira-a com
adb shell perfetto --txt -c - -o /data/misc/perfetto-traces/test <config.txt.
Traces: um perfil de CPU falha#
O simpleperf só amostra apps que são debuggable ou profileable, e o app precisa estar em execução. Para o sistema
inteiro, você precisa de uma imagem de emulador que permita adb root (não Google Play). "No samples were recorded"
significa que o app não fez nada durante a gravação: use-o e grave de novo.
Traces: o Instruments diz que o Developer Mode está desativado#
Execute sudo DevToolsSecurity -enable em um terminal, digite sua senha e grave de novo. DevToolsSecurity -status
mostra o estado atual.
Traces: o download do trace processor falha#
Ele vem de github.com/google/perfetto/releases. Atrás de um proxy, defina HTTPS_PROXY. Um arquivo que não
corresponde ao SHA-256 fixado é descartado e nunca executado. Você ainda pode abrir qualquer trace do Perfetto na UI do
Perfetto.
Crashes: nada é listado#
No Android, o sistema guarda um crash no DropBox e limita a taxa de repetições, então um app em loop é listado menos
vezes do que quebra. No iOS Simulator, o macOS grava o relatório .ips alguns segundos depois do crash, em
~/Library/Logs/DiagnosticReports; relatórios de apps que não estão na pasta de um simulador não são listados.
Pressione Refresh, ou execute emulabzip crashes.
Crashes: os nomes continuam embaralhados#
Um mapping só é usado para a versão do app para a qual foi gerado, e o crash diz qual é ("Add the mapping.txt of
com.example 1.2.0 (42)"). Adicione o arquivo exatamente com essa versão: emulabzip mappings add com.example "1.2.0 (42)" mapping.txt. Um arquivo de outro build daria nomes errados, então não é usado. Os frames também ficam como
estão quando o R8 não tinha números de linha para manter: adicione -keepattributes SourceFile,LineNumberTable às
regras do próximo build.
Crashes: o React Native mostra 1:608617 em vez de um arquivo#
Um build de release executa um bundle, e as posições dele precisam do source map desse bundle. Para o Hermes, use o mapa
composto, android/app/build/generated/sourcemaps/react/release/index.android.bundle.map, e não os packager ou
compiler. Ele também precisa ser o mapa do build que quebrou.
Crashes: o iOS mostra endereços puros#
Adicione o .dSYM do build que quebrou (emulabzip mappings add com.example.app "1.2.0 (42)" MyApp.app.dSYM). O UUID
dele precisa corresponder ao do app, então um dSYM de outro build, mesmo da mesma versão, não é usado. Ler os endereços
exige um Mac, porque usa o atos.
Bug report: nenhuma requisição com falha#
As requisições vêm do proxy em Network. Inicie-o e conecte o dispositivo antes de o bug acontecer; um relatório feito a
partir de uma sessão gravada com --network também as tem.
Controls: a localização não faz nada em um dispositivo#
Apenas emuladores aceitam uma nova localização, pelo console do emulador. Isso exige o token em
~/.emulator_console_auth_token, que o emulador cria na primeira vez que roda a partir da sua conta. Dispositivos
físicos e simuladores de outros tipos não têm suporte para localização no Android.
Controls: uma notificação não aparece no Android#
As notificações são publicadas pelo shell com cmd notification post (testado no Android 14). Ative as notificações
para o "Android Shell" se o dispositivo as esconder. O argumento de app é ignorado no Android.
Web pages: minha WebView não está listada#
Uma WebView só é listada quando o seu app chama WebView.setWebContentsDebuggingEnabled(true) (um build de debug
geralmente chama) e a página está aberta. O Chrome é listado enquanto está aberto. A lista é lida quando você abre
Frameworks e quando pressiona Refresh. No iOS, use o menu Develop do Safari; veja
Páginas web nos apps.
Flows: meus toques não são gravados#
Apenas a tela de toque é lida: toque na janela do próprio emulador. Os toques enviados pelo EmuLabZip (Interact,
Play) ou por adb shell input nunca chegam a ela, e o texto digitado não é gravado. Um toque recebe o nome da view
que atingiu apenas quando a tela foi lida a tempo, o que leva dois ou três segundos antes do toque; o ponto é guardado de
qualquer forma. Veja Entrada e fluxos.
Deep links: a verificação diz que o domínio não está verificado#
No Android, peça ao dispositivo para tentar de novo com Verify again ou emulabzip link verify <app>, e confira
depois de alguns segundos. Uma divergência de fingerprint geralmente significa que o arquivo lista a chave de release e o
build no dispositivo está assinado com a chave de debug. Um arquivo de domínio que redireciona (para www, ou de http
para https) é recusado pelos dois sistemas. Veja Deep links.
Network: uma regra de script não faz nada#
Um script só roda depois que os bytes exatos dele foram aprovados (Approve this script na regra, ou
emulabzip script approve). Altere o arquivo e ele precisa ser aprovado de novo. Se um script roda mas a requisição
continua igual, os detalhes do fluxo dizem o que o script escreveu ou por que falhou. Veja
Scripts de regra.
Plugins: um plugin não pode ser executado#
Ele precisa estar ativado antes, e editar o plugin.json dele o desativa de novo. Um plugin que termina com erro mostra
o fim da sua saída de erro. Confira se o programa em command existe (ele é procurado na pasta do plugin e depois no
PATH) e se é executável (chmod +x run.sh).
MCP: o assistente não vê nenhuma ferramenta#
Execute emulabzip mcp à mão e envie a ele uma requisição initialize, como no servidor MCP. Se o
cliente não encontrar o emulabzip, dê a ele o caminho completo. A saída padrão carrega apenas o protocolo; olhe a
saída de erro padrão (EMULABZIP_LOG=debug) para ver o que deu errado.
Obtendo diagnósticos#
Inicie o app ou a CLI com EMULABZIP_LOG=debug e inclua a saída ao
abrir uma issue.