fetch-crash-stacktrace
Retrieve Android crash stack traces from device buffers, optionally filtered by package name to isolate specific application failures.
Instructions
Pull recent crash buffer (-b crash -d -t) optionally filtered by pid resolved from package.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| packageName | No | Optional package to resolve pid; filters crash buffer with --pid | |
| maxLines | No | Tail line count from crash buffer (-b crash -t) | |
| timeoutMs | No | Timeout per adb call in milliseconds |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"maxLines": {
"default": 400,
"description": "Tail line count from crash buffer (-b crash -t)",
"maximum": 2000,
"minimum": 50,
"type": "integer"
},
"packageName": {
"description": "Optional package to resolve pid; filters crash buffer with --pid",
"minLength": 1,
"type": "string"
},
"timeoutMs": {
"default": 5000,
"description": "Timeout per adb call in milliseconds",
"maximum": 15000,
"minimum": 1000,
"type": "integer"
}
},
"type": "object"
}
Implementation Reference
- src/tools/logcatTool.js:242-253 (handler)The handler function for 'fetch-crash-stacktrace' tool. Resolves optional PID from packageName, constructs adb logcat args for crash buffer dump (-b crash -d -t N), runs the command, and returns the output or a no-entries message.async params => { const pid = params.packageName ? await resolvePid(params.packageName, params.timeoutMs) : null; const args = ['logcat', '-b', 'crash', '-d', '-t', String(params.maxLines)]; if (pid) { args.push(`--pid=${pid}`); } const output = await runAdbCommand(args, params.timeoutMs); if (!output) { return { content: [{ type: 'text', text: 'No crash entries found.' }] }; } return { content: [{ type: 'text', text: output }] }; }
- src/tools/logcatTool.js:69-89 (schema)Zod schema for input validation of the 'fetch-crash-stacktrace' tool parameters: optional packageName, maxLines (50-2000, def 400), timeoutMs (1000-15000, def 5000).const crashStackInputSchema = z.object({ packageName: z .string() .min(1) .describe('Optional package to resolve pid; filters crash buffer with --pid') .optional(), maxLines: z .number() .int() .min(50) .max(2000) .default(400) .describe('Tail line count from crash buffer (-b crash -t)'), timeoutMs: z .number() .int() .min(1000) .max(15000) .default(5000) .describe('Timeout per adb call in milliseconds') });
- src/tools/logcatTool.js:234-254 (registration)Registration of the 'fetch-crash-stacktrace' tool via server.registerTool within the registerLogcatTool function. Includes title, description, inputSchema reference, and inline handler implementation.server.registerTool( 'fetch-crash-stacktrace', { title: 'Fetch crash stacktrace (crash buffer)', description: 'Pull recent crash buffer (-b crash -d -t) optionally filtered by pid resolved from package.', inputSchema: crashStackInputSchema }, async params => { const pid = params.packageName ? await resolvePid(params.packageName, params.timeoutMs) : null; const args = ['logcat', '-b', 'crash', '-d', '-t', String(params.maxLines)]; if (pid) { args.push(`--pid=${pid}`); } const output = await runAdbCommand(args, params.timeoutMs); if (!output) { return { content: [{ type: 'text', text: 'No crash entries found.' }] }; } return { content: [{ type: 'text', text: output }] }; } );
- src/tools/logcatTool.js:135-142 (helper)Helper function to resolve process ID (PID) from Android package name using 'adb shell pidof -s'. Called by the tool handler when packageName is provided.async function resolvePid(packageName, timeoutMs) { const output = await runAdbCommand(['shell', 'pidof', '-s', packageName], timeoutMs); const pid = output.split(/\s+/).find(Boolean); if (!pid) { throw new Error(`Could not resolve pid for package ${packageName}`); } return pid; }
- src/tools/logcatTool.js:118-133 (helper)Core utility function to execute adb commands asynchronously with configurable timeout, large buffer, stdout trimming, and comprehensive error handling including stderr.async function runAdbCommand(args, timeoutMs) { try { const { stdout } = await execFileAsync('adb', args, { timeout: timeoutMs, maxBuffer: 5 * 1024 * 1024 }); return stdout.trimEnd(); } catch (error) { const stderr = error && typeof error.stderr === 'string' ? error.stderr.trim() : ''; const message = [`adb ${args.join(' ')} failed`, error.message].filter(Boolean).join(': '); if (stderr) { throw new Error(`${message} | stderr: ${stderr}`); } throw new Error(message); } }