Skip to content

Debugging

Debugging aids for a connected device.

  • get_process_exit_history — adb shell dumpsys activity exit-info <pkg>: ActivityManager's bounded ApplicationExitInfo ring, parsed into typed records (reason, timestamp, pid, importance, pss/rss, trace availability).
  • set_debug_app / clear_debug_app — adb shell am set-debug-app [-w] [--persistent] <pkg> / am clear-debug-app. Marks (or clears) ActivityManager's debug app; does not attach a debugger.
  • list_jdwp_processes — adb jdwp: PIDs of processes currently exposing a JDWP transport (a snapshot, since adb jdwp streams and never exits).
  • capture_native_backtrace — adb shell debuggerd -b <pid>: native thread backtraces for a running process, parsed to a per-thread summary plus the capped full text. Privileged on production builds.
  • capture_native_tombstone — adb shell debuggerd <pid>: a full native tombstone written into ADB_AUTOMATION_LOCAL_ROOT/tombstones/; returns path + parsed header metadata, not contents.

capture_native_backtrace

Capture native thread backtraces for a running process: adb shell debuggerd -b <pid>.

Dumps every thread's native call stack without stopping the process. Returns the parsed header (process name, ABI), a per-thread summary (name / tid / frame count), and the full backtrace text (capped). This is a privileged operation on production builds — a device that isn't rooted/userdebug rejects it.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required
pid int

The process id to backtrace (a positive integer — see processes.get_process_id / list_processes).

required

Returns:

Type Description
NativeBacktrace

The serial and pid; process_name and abi from the dump header; thread_count and threads (name / sys_tid / frame_count per thread); and text (the full dump, truncated if very large).

Error handling

A non-positive pid raises INVALID_ARGUMENT before anything runs. An unknown serial raises DEVICE_NOT_FOUND. A device that requires root for debuggerd, or otherwise refuses it, raises PERMISSION_DENIED. A dead or invalid pid (debuggerd produced no backtrace) raises BACKEND_ERROR.

Example

Called with serial="emulator-5554", pid=1224. A typical (trimmed) response:

{
  "status": "success",
  "message": "capture_native_backtrace completed successfully.",
  "data": {
    "serial": "emulator-5554",
    "pid": 1224,
    "process_name": "com.android.systemui",
    "abi": "x86_64",
    "thread_count": 2,
    "threads": [
      {"name": "ndroid.systemui", "sys_tid": 1224, "frame_count": 17}
    ],
    "text": "----- pid 1224 at ... -----\nCmd line: com.android.systemui\n..."
  },
  "error": null
}

capture_native_tombstone

Request a full native tombstone for a process and save it to the host: adb shell debuggerd <pid>.

Triggers a full crash-style dump (registers, memory map, all thread backtraces) for a running process and writes the human-readable tombstone text into <ADB_AUTOMATION_LOCAL_ROOT>/tombstones/. Categorized write because it's a high-impact diagnostic that briefly pauses the target's threads, and is privileged on production builds. The tombstone bytes are not embedded in the response — only the saved path and parsed metadata.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required
pid int

The process id to dump (a positive integer).

required
local_path str

Destination path relative to the server's local_root tombstones/ directory, e.g. "sysui.txt" or "run1/sysui.txt". Must resolve inside local_root.

required

Returns:

Type Description
NativeTombstone

The serial and pid; process_name / abi / signal from the header; frame_count (the "N total frames" value); device_tombstone_ref (the tombstone_NN.pb filename the dump names on the device, if any); local_path (the absolute host path written); and size_bytes.

Error handling

A non-positive pid raises INVALID_ARGUMENT. No configured local_root, or a local_path escaping it, raises POLICY_DENIED. An unknown serial raises DEVICE_NOT_FOUND. A device that requires root for debuggerd, or refuses it, raises PERMISSION_DENIED. A dead or invalid pid raises BACKEND_ERROR.

Example

Called with serial="emulator-5554", pid=1224, local_path="sysui.txt". A typical response:

{
  "status": "success",
  "message": "Saved native tombstone for pid 1224 on emulator-5554 to /data/out/tombstones/sysui.txt.",
  "data": {
    "serial": "emulator-5554",
    "pid": 1224,
    "process_name": "com.android.systemui",
    "abi": "x86_64",
    "signal": "35 (<debuggerd signal>), code -1 (SI_QUEUE from pid 7338, uid 0), fault addr --------",
    "frame_count": 24,
    "device_tombstone_ref": "tombstone_27.pb",
    "local_path": "/data/out/tombstones/sysui.txt",
    "size_bytes": 18244,
    "success": true
  },
  "error": null
}

clear_debug_app

Clear ActivityManager's configured debug app: adb shell am clear-debug-app.

Undoes a previous set_debug_app. Idempotent — calling it when no debug app is set is a successful no-op, and cleared being true does not imply one had been configured.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required

Returns:

Type Description
ClearDebugAppResult

The serial and cleared (always true on success).

Error handling

An unknown serial or unresponsive adb binary raises DEVICE_NOT_FOUND/ADB_UNAVAILABLE. A permission rejection raises PERMISSION_DENIED; any other non-zero exit raises BACKEND_ERROR.

Example

Called with serial="emulator-5554". A typical response:

{
  "status": "success",
  "message": "Cleared the debug app on emulator-5554.",
  "data": {"serial": "emulator-5554", "cleared": true},
  "error": null
}

get_process_exit_history

Get a package's recent process-exit records: adb shell dumpsys activity exit-info <package>.

ActivityManager keeps a bounded ApplicationExitInfo ring per package. This parses it into typed records — reason (crash / ANR / low-memory kill / self-exit / signalled), timestamp, pid, importance, pss/rss, and whether a trace was captured — so an agent can explain why an app died. Reading only. A package with no retained history returns an empty list, not an error.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required
package str

The package to look up, e.g. "com.example.app".

required

Returns:

Type Description
ProcessExitHistory

The serial / package / count, and records (newest first). Each record has timestamp, pid, real_uid, user, process, reason_code + reason label, subreason_code + subreason label, status, importance, pss and rss (the raw strings the dump reports), state, description, trace_available (bool), and has_anr_info (bool). Fields the record didn't carry are null.

Error handling

A blank package raises INVALID_ARGUMENT before anything runs. An unknown serial or unresponsive adb binary raises DEVICE_NOT_FOUND/ADB_UNAVAILABLE. A permission rejection raises PERMISSION_DENIED; any other non-zero exit raises BACKEND_ERROR. An unknown package or one with no history is an empty result, not an error.

Example

Called with serial="emulator-5554", package="com.example.app". A typical response:

{
  "status": "success",
  "message": "2 exit records for com.example.app on emulator-5554 (newest: APP CRASH(EXCEPTION) at 2026-09-06 22:39:39.266).",
  "data": {
    "serial": "emulator-5554",
    "package": "com.example.app",
    "count": 2,
    "records": [
      {
        "timestamp": "2026-09-06 22:39:39.266",
        "pid": 5486,
        "real_uid": 10234,
        "user": 0,
        "process": "com.example.app",
        "reason_code": 4,
        "reason": "APP CRASH(EXCEPTION)",
        "subreason_code": 0,
        "subreason": "UNKNOWN",
        "status": 0,
        "importance": 400,
        "pss": "0.00",
        "rss": "167MB",
        "state": "empty",
        "description": "crash",
        "trace_available": false,
        "has_anr_info": false
      }
    ]
  },
  "error": null
}

list_jdwp_processes

List processes exposing a JDWP transport: adb jdwp.

Returns the PIDs of the device's debuggable processes that currently have a Java Debug Wire Protocol endpoint open — the candidates you can attach a debugger or jdb to. adb jdwp streams and never exits on its own, so this returns a snapshot taken after a short settle window.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required

Returns:

Type Description
JdwpProcessList

The serial, count, and pids (a list of integers, in first-seen order, deduplicated). An empty list is a normal result.

Error handling

An unknown/offline serial raises DEVICE_NOT_FOUND; the adb binary being unreachable raises ADB_UNAVAILABLE. Any other non-zero exit raises BACKEND_ERROR. Non-numeric lines in the output are ignored.

Example

Called with serial="emulator-5554". A typical response:

{
  "status": "success",
  "message": "3 JDWP-debuggable process(es) on emulator-5554: [1224, 1568, 2411].",
  "data": {"serial": "emulator-5554", "count": 3, "pids": [1224, 1568, 2411]},
  "error": null
}

set_debug_app

Mark an app as ActivityManager's debug app: adb shell am set-debug-app.

Records package as the debug app so its next launch is debugger-friendly. This does NOT attach a debugger — it only sets the marker. With wait_for_debugger the next launch of the app blocks until a debugger connects (-w); with persistent the setting survives reboot (--persistent). Pair with clear_debug_app when done.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required
package str

The package to mark, e.g. "com.example.app".

required
wait_for_debugger bool

Block the app's next launch until a debugger attaches (-w).

False
persistent bool

Keep the setting across reboots (--persistent).

False

Returns:

Type Description
SetDebugAppResult

The serial, package, and the wait_for_debugger / persistent flags that were applied.

Error handling

A blank package raises INVALID_ARGUMENT before anything runs. An unknown serial or unresponsive adb binary raises DEVICE_NOT_FOUND/ADB_UNAVAILABLE. A permission rejection raises PERMISSION_DENIED; any other non-zero exit raises BACKEND_ERROR. An unknown package is NOT an error — am doesn't validate it.

Example

Called with serial="emulator-5554", package="com.example.app", wait_for_debugger=true. A typical response:

{
  "status": "success",
  "message": "Set com.example.app as the debug app on emulator-5554 (waits for debugger on next launch).",
  "data": {
    "serial": "emulator-5554",
    "package": "com.example.app",
    "wait_for_debugger": true,
    "persistent": false
  },
  "error": null
}