perfetto-analyzer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -0
- package/bin/cli.js +117 -0
- package/package.json +31 -0
- package/skill/SKILL.md +234 -0
- package/skill/references/adb-quick-start.md +139 -0
- package/skill/references/metrics-interpretation.md +130 -0
- package/skill/references/perfetto-traces-reference.md +116 -0
- package/skill/scripts/analyze_metrics.py +408 -0
- package/skill/scripts/collect_trace.py +204 -0
- package/skill/scripts/configs/all.textproto +111 -0
- package/skill/scripts/configs/battery.textproto +65 -0
- package/skill/scripts/configs/cpu.textproto +68 -0
- package/skill/scripts/configs/frames.textproto +62 -0
- package/skill/scripts/configs/memory.textproto +57 -0
- package/skill/scripts/generate_report.py +397 -0
- package/skill/scripts/parse_perfetto_pb.py +469 -0
- package/skill/scripts/requirements.txt +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# perfetto-analyzer
|
|
2
|
+
|
|
3
|
+
AI skill for Android performance analysis using [Perfetto](https://perfetto.dev).
|
|
4
|
+
|
|
5
|
+
Automatically installs into all supported AI agents on your machine.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Run once — installs for all supported agents
|
|
11
|
+
npx perfetto-analyzer install
|
|
12
|
+
|
|
13
|
+
# Or install globally (auto-installs via postinstall)
|
|
14
|
+
npm install -g perfetto-analyzer
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Supported AI Agents
|
|
18
|
+
|
|
19
|
+
| Agent | Skills directory |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Claude Code | `~/.claude/skills/perfetto-analyzer/` |
|
|
22
|
+
| GitHub Copilot | `~/.github/copilot/skills/perfetto-analyzer/` |
|
|
23
|
+
| Cursor | `~/.cursor/skills/perfetto-analyzer/` |
|
|
24
|
+
| Antigravity | `~/.antigravity/skills/perfetto-analyzer/` |
|
|
25
|
+
| Codex (OpenAI) | `~/.codex/skills/perfetto-analyzer/` |
|
|
26
|
+
| Devin | `~/.devin/skills/perfetto-analyzer/` |
|
|
27
|
+
|
|
28
|
+
Directories are created automatically if they don't exist.
|
|
29
|
+
|
|
30
|
+
## Uninstall
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx perfetto-analyzer uninstall
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## What it does
|
|
37
|
+
|
|
38
|
+
After installation, ask your AI assistant to analyze an Android app's performance:
|
|
39
|
+
|
|
40
|
+
- **Collect a trace** from a connected device via `adb`
|
|
41
|
+
- **Analyze CPU, memory, frames (jank), and battery** from a `.pb` Perfetto trace
|
|
42
|
+
- **Generate a markdown report** with insights and actionable recommendations
|
|
43
|
+
|
|
44
|
+
### Prerequisites
|
|
45
|
+
|
|
46
|
+
- `adb` installed and in PATH (Android SDK Platform-Tools)
|
|
47
|
+
- Python 3.9+
|
|
48
|
+
- `pip install perfetto`
|
|
49
|
+
|
|
50
|
+
## Usage example
|
|
51
|
+
|
|
52
|
+
> "Analyze the performance of com.myapp.debug, collect a 30s frames trace"
|
|
53
|
+
|
|
54
|
+
The skill will:
|
|
55
|
+
1. Verify the device is connected
|
|
56
|
+
2. Launch the app if it isn't running
|
|
57
|
+
3. Collect the Perfetto trace
|
|
58
|
+
4. Parse callstacks and frame timelines
|
|
59
|
+
5. Generate a report with hotspots and jank causes
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const SKILL_NAME = "perfetto-analyzer";
|
|
8
|
+
const SKILL_SRC = path.join(__dirname, "..", "skill");
|
|
9
|
+
|
|
10
|
+
const AGENTS = [
|
|
11
|
+
{ name: "Claude Code", dir: path.join(os.homedir(), ".claude", "skills") },
|
|
12
|
+
{ name: "GitHub Copilot", dir: path.join(os.homedir(), ".github", "copilot", "skills") },
|
|
13
|
+
{ name: "Cursor", dir: path.join(os.homedir(), ".cursor", "skills") },
|
|
14
|
+
{ name: "Antigravity", dir: path.join(os.homedir(), ".antigravity", "skills") },
|
|
15
|
+
{ name: "Codex", dir: path.join(os.homedir(), ".codex", "skills") },
|
|
16
|
+
{ name: "Devin", dir: path.join(os.homedir(), ".devin", "skills") },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
function copyDir(src, dest) {
|
|
20
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
21
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
22
|
+
const srcPath = path.join(src, entry.name);
|
|
23
|
+
const destPath = path.join(dest, entry.name);
|
|
24
|
+
if (entry.isDirectory()) {
|
|
25
|
+
copyDir(srcPath, destPath);
|
|
26
|
+
} else {
|
|
27
|
+
fs.copyFileSync(srcPath, destPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function removeDir(dir) {
|
|
33
|
+
if (fs.existsSync(dir)) {
|
|
34
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function padEnd(str, len) {
|
|
41
|
+
return str + " ".repeat(Math.max(0, len - str.length));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function install(silent) {
|
|
45
|
+
if (!silent) {
|
|
46
|
+
console.log(`\nInstalling ${SKILL_NAME} skill...\n`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (const agent of AGENTS) {
|
|
50
|
+
const dest = path.join(agent.dir, SKILL_NAME);
|
|
51
|
+
try {
|
|
52
|
+
copyDir(SKILL_SRC, dest);
|
|
53
|
+
if (!silent) {
|
|
54
|
+
console.log(` ✓ ${padEnd(agent.name, 16)} → ${dest}`);
|
|
55
|
+
}
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error(` ✗ ${padEnd(agent.name, 16)} ERRO: ${err.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!silent) {
|
|
62
|
+
console.log(`\nDone! Restart your AI assistant to activate the skill.\n`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function uninstall() {
|
|
67
|
+
console.log(`\nRemoving ${SKILL_NAME} skill...\n`);
|
|
68
|
+
|
|
69
|
+
for (const agent of AGENTS) {
|
|
70
|
+
const dest = path.join(agent.dir, SKILL_NAME);
|
|
71
|
+
const removed = removeDir(dest);
|
|
72
|
+
if (removed) {
|
|
73
|
+
console.log(` ✓ ${padEnd(agent.name, 16)} removed`);
|
|
74
|
+
} else {
|
|
75
|
+
console.log(` - ${padEnd(agent.name, 16)} not found (skipped)`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`\nDone!\n`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function showHelp() {
|
|
83
|
+
console.log(`
|
|
84
|
+
${SKILL_NAME} — AI skill for Android performance analysis using Perfetto
|
|
85
|
+
|
|
86
|
+
Usage:
|
|
87
|
+
npx ${SKILL_NAME} Install skill for all supported AI agents
|
|
88
|
+
npx ${SKILL_NAME} install Install skill for all supported AI agents
|
|
89
|
+
npx ${SKILL_NAME} uninstall Remove skill from all AI agent directories
|
|
90
|
+
npx ${SKILL_NAME} help Show this help
|
|
91
|
+
|
|
92
|
+
Supported agents:
|
|
93
|
+
${AGENTS.map((a) => ` - ${a.name}`).join("\n")}
|
|
94
|
+
`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const args = process.argv.slice(2);
|
|
98
|
+
const command = args[0] || "install";
|
|
99
|
+
const isPostinstall = args.includes("--postinstall");
|
|
100
|
+
|
|
101
|
+
switch (command) {
|
|
102
|
+
case "install":
|
|
103
|
+
install(isPostinstall);
|
|
104
|
+
break;
|
|
105
|
+
case "uninstall":
|
|
106
|
+
uninstall();
|
|
107
|
+
break;
|
|
108
|
+
case "help":
|
|
109
|
+
case "--help":
|
|
110
|
+
case "-h":
|
|
111
|
+
showHelp();
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
console.error(`Unknown command: ${command}`);
|
|
115
|
+
showHelp();
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "perfetto-analyzer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI skill for Android performance analysis using Perfetto — works with Claude Code, Cursor, GitHub Copilot, Codex, Antigravity and Devin",
|
|
5
|
+
"bin": {
|
|
6
|
+
"perfetto-analyzer": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"skill/"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"postinstall": "node bin/cli.js install --postinstall"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"android",
|
|
17
|
+
"perfetto",
|
|
18
|
+
"performance",
|
|
19
|
+
"tracing",
|
|
20
|
+
"claude",
|
|
21
|
+
"cursor",
|
|
22
|
+
"copilot",
|
|
23
|
+
"codex",
|
|
24
|
+
"skill",
|
|
25
|
+
"ai-agent"
|
|
26
|
+
],
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=14"
|
|
30
|
+
}
|
|
31
|
+
}
|
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: perfetto-analyzer
|
|
3
|
+
description: >
|
|
4
|
+
Analisa performance de apps Android usando Perfetto — abstrai adb, configuração de traces e interpretação de métricas.
|
|
5
|
+
Use quando o usuário quiser medir performance de um app Android, coletar traces, analisar memória (heap), CPU,
|
|
6
|
+
frames dropados, battery drain, ou quando mencionar Perfetto, profiling, trace .pb, jank, ANR, ou quiser entender
|
|
7
|
+
gargalos de performance no Android. Também use quando o usuário tiver um arquivo .pb do Perfetto e quiser insights.
|
|
8
|
+
Dispare mesmo que o usuário não mencione Perfetto explicitamente — se ele falar em "app lento", "memória crescendo",
|
|
9
|
+
"frames dropando", "CPU alta", "bateria acabando rápido" no contexto Android, esta skill é o caminho.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Perfetto Analyzer
|
|
13
|
+
|
|
14
|
+
Você é especialista em performance Android usando Perfetto. Seu papel é:
|
|
15
|
+
1. **Coletar traces** via `adb` (Modo A) ou **analisar traces existentes** (Modo B)
|
|
16
|
+
2. **Interpretar métricas** de memória, CPU, frames e battery
|
|
17
|
+
3. **Gerar relatório markdown** com insights e recomendações acionáveis
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Antes de começar — perguntas obrigatórias
|
|
22
|
+
|
|
23
|
+
Antes de executar qualquer script, colete as informações necessárias perguntando ao usuário. **Nunca assuma valores padrão para duração ou tipo de trace** — são escolhas do usuário, não técnicas.
|
|
24
|
+
|
|
25
|
+
**Modo A (Coleta automática)** — device Android conectado:
|
|
26
|
+
|
|
27
|
+
Pergunte explicitamente (em uma única mensagem):
|
|
28
|
+
1. **Package** do app — se não souber, sugira `adb shell pm list packages | grep <nome>` para descobrir
|
|
29
|
+
2. **Tipo de trace** — apresente as opções: `frames` (jank/UI), `memory` (heap/leak), `cpu` (bottlenecks), `battery` (drain), `all` (análise completa)
|
|
30
|
+
3. **Duração** — quantos segundos de gravação? Dica: 10–15s para fluxos específicos, 30s+ para leaks/battery
|
|
31
|
+
|
|
32
|
+
Só execute o script após ter as três respostas.
|
|
33
|
+
|
|
34
|
+
**Modo B (Análise de trace existente)** — usuário tem arquivo `.pb`:
|
|
35
|
+
→ Precisa apenas do caminho do arquivo. Prossiga diretamente para a análise.
|
|
36
|
+
|
|
37
|
+
Se não ficou claro qual modo o usuário quer, pergunte antes de qualquer ação.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Pré-requisitos
|
|
42
|
+
|
|
43
|
+
| Ferramenta | Como verificar | Instalação |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `adb` | `adb version` | Android SDK Platform-Tools |
|
|
46
|
+
| Python 3.9+ | `python3 --version` | python.org |
|
|
47
|
+
| `perfetto_trace_processor` (Python) | `python3 -c "import perfetto"` | `pip install perfetto` |
|
|
48
|
+
|
|
49
|
+
Verifique antes de executar. Se faltar algo, oriente o usuário.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Modo A — Coleta via adb
|
|
54
|
+
|
|
55
|
+
### 1. Verificar device conectado
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
adb devices
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Se `no devices` ou `offline`, oriente o usuário a:
|
|
62
|
+
- Ativar Opções do Desenvolvedor no Android
|
|
63
|
+
- Ativar Depuração USB
|
|
64
|
+
- Aceitar a permissão no device
|
|
65
|
+
|
|
66
|
+
### 2. Coletar o trace
|
|
67
|
+
|
|
68
|
+
Execute o script de coleta:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python3 <SKILL_DIR>/scripts/collect_trace.py \
|
|
72
|
+
--package <PACKAGE> \
|
|
73
|
+
--type <TRACE_TYPE> \
|
|
74
|
+
--duration <SEGUNDOS> \
|
|
75
|
+
--output /tmp/perfetto_trace.pb
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Onde `<TRACE_TYPE>` é um dos: `memory`, `cpu`, `frames`, `battery`, `all`
|
|
79
|
+
|
|
80
|
+
O script vai:
|
|
81
|
+
- Empurrar a config pro device via `adb push`
|
|
82
|
+
- Executar `adb shell perfetto` com a config
|
|
83
|
+
- Aguardar a duração especificada
|
|
84
|
+
- Puxar o arquivo `.pb` para `/tmp/perfetto_trace.pb`
|
|
85
|
+
|
|
86
|
+
Aguarde e mostre progresso ao usuário (o trace pode levar alguns segundos).
|
|
87
|
+
|
|
88
|
+
Após coleta bem-sucedida, prossiga para a etapa de análise.
|
|
89
|
+
|
|
90
|
+
### 3. Instalar dependências se necessário
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install perfetto 2>/dev/null || pip3 install perfetto
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Modo B — Análise de trace existente
|
|
99
|
+
|
|
100
|
+
Use o arquivo `.pb` fornecido como entrada para a análise.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cp <ARQUIVO_DO_USUARIO> /tmp/perfetto_trace.pb
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Análise do Trace
|
|
109
|
+
|
|
110
|
+
### Passo 1: Parsing
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python3 <SKILL_DIR>/scripts/parse_perfetto_pb.py \
|
|
114
|
+
--input /tmp/perfetto_trace.pb \
|
|
115
|
+
--output /tmp/perfetto_parsed.json \
|
|
116
|
+
--package <PACKAGE>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
O script extrai via SQL queries na Trace Processor API:
|
|
120
|
+
- Alocações de heap (nativo + ART)
|
|
121
|
+
- Samples de CPU por callstack
|
|
122
|
+
- Frame timeline (frames renderizados vs dropados)
|
|
123
|
+
- Contadores de battery
|
|
124
|
+
|
|
125
|
+
### Passo 2: Análise de métricas
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
python3 <SKILL_DIR>/scripts/analyze_metrics.py \
|
|
129
|
+
--input /tmp/perfetto_parsed.json \
|
|
130
|
+
--output /tmp/perfetto_insights.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Calcula: top callstacks, percentis de frame, anomalias, recomendações.
|
|
134
|
+
|
|
135
|
+
### Passo 3: Gerar relatório
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
python3 <SKILL_DIR>/scripts/generate_report.py \
|
|
139
|
+
--insights /tmp/perfetto_insights.json \
|
|
140
|
+
--package <PACKAGE_OU_UNKNOWN> \
|
|
141
|
+
--trace-type <TIPO_OU_all>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
O relatório vai para stdout. Apresente ao usuário formatado como markdown.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Formato do Relatório
|
|
149
|
+
|
|
150
|
+
O relatório gerado segue este template. Apresente-o completo, sem truncar:
|
|
151
|
+
|
|
152
|
+
```markdown
|
|
153
|
+
# Relatório de Performance — <package>
|
|
154
|
+
**Dispositivo:** <device> | **Data:** <data> | **Duração:** <Xs> | **Tipo:** <tipo>
|
|
155
|
+
|
|
156
|
+
## Resumo Executivo
|
|
157
|
+
> Top 3-5 findings mais críticos, em ordem de impacto
|
|
158
|
+
|
|
159
|
+
## Memória
|
|
160
|
+
### Maiores Alocadores (Heap Nativo)
|
|
161
|
+
<tabela: callstack | bytes não-liberados | % total>
|
|
162
|
+
|
|
163
|
+
### Objetos Java/Kotlin Retidos (ART)
|
|
164
|
+
<tabela: classe | instâncias | bytes>
|
|
165
|
+
|
|
166
|
+
### Alertas
|
|
167
|
+
- ⚠️ [se heap churn alto, possível leak, etc.]
|
|
168
|
+
|
|
169
|
+
## CPU
|
|
170
|
+
### Top Funções (Self Time)
|
|
171
|
+
<tabela: função | thread | % CPU>
|
|
172
|
+
|
|
173
|
+
### Callstacks Mais Frequentes
|
|
174
|
+
<top 5 por ocorrência>
|
|
175
|
+
|
|
176
|
+
### Alertas
|
|
177
|
+
- ⚠️ [se main thread bloqueada, GC excessivo, etc.]
|
|
178
|
+
|
|
179
|
+
## Frames
|
|
180
|
+
| Métrica | Valor | Threshold OK |
|
|
181
|
+
|---|---|---|
|
|
182
|
+
| Total de frames | N | — |
|
|
183
|
+
| Frames dropados | N (X%) | < 1% |
|
|
184
|
+
| Frame P50 | Xms | < 16ms |
|
|
185
|
+
| Frame P95 | Xms | < 32ms |
|
|
186
|
+
| Frame P99 | Xms | < 50ms |
|
|
187
|
+
|
|
188
|
+
### Causas de Jank
|
|
189
|
+
<tabela: causa | ocorrências>
|
|
190
|
+
|
|
191
|
+
## Battery
|
|
192
|
+
| Métrica | Valor |
|
|
193
|
+
|---|---|
|
|
194
|
+
| Carga drenada | X mC (miliCoulombs) |
|
|
195
|
+
| Duração do trace | Xs |
|
|
196
|
+
| Taxa média de drain | X mC/s |
|
|
197
|
+
|
|
198
|
+
### Top Consumidores
|
|
199
|
+
<tabela: componente | consumo estimado>
|
|
200
|
+
|
|
201
|
+
## Recomendações
|
|
202
|
+
1. **[Título]** — [Descrição do problema + ação concreta]
|
|
203
|
+
2. ...
|
|
204
|
+
|
|
205
|
+
## Próximos Passos
|
|
206
|
+
- [ ] Verificar X em flame graph no perfetto.dev/ui
|
|
207
|
+
- [ ] Correlacionar Y com Z
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Referências
|
|
213
|
+
|
|
214
|
+
Leia estes arquivos quando precisar de mais contexto:
|
|
215
|
+
|
|
216
|
+
| Arquivo | Quando ler |
|
|
217
|
+
|---|---|
|
|
218
|
+
| `references/perfetto-traces-reference.md` | Quais traces coletar, configs textproto, quando usar cada um |
|
|
219
|
+
| `references/metrics-interpretation.md` | O que significa cada métrica, thresholds, red flags |
|
|
220
|
+
| `references/adb-quick-start.md` | Setup adb, troubleshooting de device, permissões |
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Erros Comuns
|
|
225
|
+
|
|
226
|
+
**`no devices/emulators found`** → Verificar USB debugging e `adb devices`
|
|
227
|
+
|
|
228
|
+
**`ImportError: No module named 'perfetto'`** → `pip install perfetto`
|
|
229
|
+
|
|
230
|
+
**`Error opening trace file`** → Arquivo .pb corrompido ou versão incompatível do Perfetto. Tentar reabrir no perfetto.dev/ui para validar.
|
|
231
|
+
|
|
232
|
+
**Trace vazio ou sem dados** → App pode não ter sido usada durante a coleta. Instruir o usuário a interagir com o app durante a gravação.
|
|
233
|
+
|
|
234
|
+
**`permission denied` no device** → `adb shell su -c perfetto ...` (requer root) ou usar heapprofd com `run-as`
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# ADB Quick Start — Setup para Perfetto
|
|
2
|
+
|
|
3
|
+
## Instalação do adb
|
|
4
|
+
|
|
5
|
+
### macOS
|
|
6
|
+
```bash
|
|
7
|
+
brew install android-platform-tools
|
|
8
|
+
# ou baixar manualmente:
|
|
9
|
+
# https://developer.android.com/tools/releases/platform-tools
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Linux (Ubuntu/Debian)
|
|
13
|
+
```bash
|
|
14
|
+
sudo apt install android-tools-adb
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Verificar instalação
|
|
18
|
+
```bash
|
|
19
|
+
adb version
|
|
20
|
+
# Android Debug Bridge version 1.0.41
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Conectar device
|
|
26
|
+
|
|
27
|
+
### Via USB (recomendado para traces)
|
|
28
|
+
|
|
29
|
+
1. No Android: **Configurações → Sobre o dispositivo → Número da compilação** (toque 7x)
|
|
30
|
+
2. **Configurações → Opções do desenvolvedor → Depuração USB** → Ativar
|
|
31
|
+
3. Conectar cabo USB
|
|
32
|
+
4. Aceitar prompt "Permitir depuração USB?" no device (marque "Sempre permitir")
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
adb devices
|
|
36
|
+
# List of devices attached
|
|
37
|
+
# XXXXXXXX device ← OK
|
|
38
|
+
# XXXXXXXX offline ← Precisa aceitar no device
|
|
39
|
+
# XXXXXXXX unauthorized ← Precisa aceitar no device
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Via Wi-Fi (Android 11+)
|
|
43
|
+
|
|
44
|
+
1. **Opções do desenvolvedor → Depuração sem fio**
|
|
45
|
+
2. **Parear device** → anotar IP:porta
|
|
46
|
+
3. `adb pair <ip>:<porta>`
|
|
47
|
+
4. `adb connect <ip>:<porta>`
|
|
48
|
+
|
|
49
|
+
**Atenção:** Traces via Wi-Fi podem ser mais lentos para fazer `pull`. Para traces grandes (> 50 MB), prefira USB.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Troubleshooting
|
|
54
|
+
|
|
55
|
+
### `no devices/emulators found`
|
|
56
|
+
```bash
|
|
57
|
+
# Reiniciar servidor adb
|
|
58
|
+
adb kill-server
|
|
59
|
+
adb start-server
|
|
60
|
+
adb devices
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `device offline` ou `unauthorized`
|
|
64
|
+
- Desconectar e reconectar cabo
|
|
65
|
+
- Aceitar prompt no device
|
|
66
|
+
- Se persistir: **Opções do desenvolvedor → Revogar autorizações de depuração USB** e re-autorizar
|
|
67
|
+
|
|
68
|
+
### `permission denied` ao executar Perfetto no device
|
|
69
|
+
|
|
70
|
+
O Perfetto requer permissão para coletar traces. Em Android 9+, o `traced` daemon já está rodando e aceita conexões de apps com permissão ou via shell.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Verificar se traced está rodando
|
|
74
|
+
adb shell pgrep -a traced
|
|
75
|
+
|
|
76
|
+
# Se não estiver:
|
|
77
|
+
adb shell setprop persist.traced.enable 1
|
|
78
|
+
adb shell start traced
|
|
79
|
+
adb shell start traced_probes
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Para heap profiling (heapprofd), o app precisa ser debuggable OU o device precisa estar rootado:
|
|
83
|
+
```bash
|
|
84
|
+
# Verificar se app é debuggable
|
|
85
|
+
adb shell pm dump <PACKAGE> | grep DEBUGGABLE
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Se o app não for debuggable, use um build de debug ou:
|
|
89
|
+
```bash
|
|
90
|
+
# Root: habilitar profiling em release builds
|
|
91
|
+
adb shell setprop security.perf_harden 0
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `Error: Detach failed`
|
|
95
|
+
|
|
96
|
+
Alguns devices exigem:
|
|
97
|
+
```bash
|
|
98
|
+
adb shell "echo 0 > /proc/sys/kernel/perf_event_paranoid"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Coleta manual via adb (referência)
|
|
104
|
+
|
|
105
|
+
O método mais robusto usa `adb exec-out` com stdin/stdout — sem gravar nada no device:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Config via stdin, trace via stdout — sem permissões no device
|
|
109
|
+
cat frames.textproto | adb exec-out perfetto --txt -c - -o - > /tmp/trace.pb
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Funciona em emuladores e devices físicos porque:
|
|
113
|
+
- `--txt` indica config em texto (textproto)
|
|
114
|
+
- `-c -` lê a config de stdin
|
|
115
|
+
- `-o -` escreve o trace em stdout
|
|
116
|
+
- `adb exec-out` transfere binário sem conversão de newlines (ao contrário de `adb shell`)
|
|
117
|
+
|
|
118
|
+
**Importante:** Não use `-o /sdcard/...` — o daemon do Perfetto roda com UID diferente do shell e não tem permissão de escrita no sdcard. Use stdout (`-o -`) ou `/data/misc/perfetto-traces/` (que exige pull separado).
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Comandos úteis durante troubleshooting de trace
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Ver logs do sistema em tempo real
|
|
126
|
+
adb logcat -s perfetto traced heapprofd
|
|
127
|
+
|
|
128
|
+
# Verificar se o traced daemon está rodando
|
|
129
|
+
adb shell pgrep -a traced
|
|
130
|
+
|
|
131
|
+
# Ativar daemon manualmente se não estiver rodando
|
|
132
|
+
adb shell setprop persist.traced.enable 1 && adb shell start traced
|
|
133
|
+
|
|
134
|
+
# Listar processos do app
|
|
135
|
+
adb shell ps -ef | grep <PACKAGE>
|
|
136
|
+
|
|
137
|
+
# Ver PID do app (útil para heapprofd)
|
|
138
|
+
adb shell pidof <PACKAGE>
|
|
139
|
+
```
|