Zygote
Hands-on labsbeginner

Lab 4 — logcat

Read the system log without drowning: filter by tag, PID, buffer and priority, capture a crash, and understand why the buffer you are reading may not be the one you think.

5 minAPI 1–37 · 17verified 2026-10-27

logcat is the first tool everyone reaches for and the last one anyone masters. The default output is a firehose, and the skill is not reading it — it is filtering it down to the twenty lines that matter.

TL;DR#

  • Every log line has a priority, a tag, a PID and a buffer. Filter on at least two of them.
  • -b chooses the buffer. main is app logs, system is system logs, crash is crashes, events is the binary event log.
  • --pid filters to one process, which is usually what you want when debugging an app.
  • -c clears and -d dumps then exits. Both are useful; both surprise people.
  • A crash appears in the crash buffer, not always in main.

Mental model#

Think of a building's fire alarm panel.

The panel shows every zone, every alarm and every test, all at once. Reading it raw is useless. What you actually do is look at one zone, at one time, and compare it with what you expected.

logcat is that panel. The zones are tags and buffers; the time window is a filter; and the comparison is why you need to know what normal looks like before you can spot abnormal.

Where the analogy breaks#

An alarm panel is designed to be read by a human at a glance. logcat is designed to be written by code at line rate, and its output is a debugging stream, not a status display. That is why the volume is enormous and why the right approach is to reduce, not to read faster.

Deep dive#

Anatomy of a line#

A log line has a timestamp, a PID, a TID, a priority, a tag and a message. The default format is close to:

01-01 12:00:00.000  1234  1234 I ActivityManager: Start proc 5678:com.example/u0a123 for activity

The fields that matter:

FieldMeaning
PriorityV verbose, D debug, I info, W warn, E error, F fatal
TagThe component that logged, such as ActivityManager
PID/TIDProcess and thread IDs
MessageThe content

Filters are tag:priority. ActivityManager:I *:S means "ActivityManager at info or above, everything else silent". That *:S is the part people forget, and it is what turns a firehose into a stream.

Buffers#

Android keeps several log buffers. -b selects one:

  • main — app and framework logs. The default.
  • system — system daemon logs.
  • crash — crash reports, including Java stack traces and native crashes.
  • events — binary event log used by logcat -b events and by stats tooling.
  • all — all of the above.

A crash that does not appear in main is usually in crash. That single fact saves a lot of time.

Filtering to one process#

The most useful filter is the process:

adb shell pidof com.example.app
adb logcat --pid=<pid>

--pid filters to a single process, which removes almost all the noise. Combine it with a priority filter when the process is chatty.

The alternative is tag filtering, which is better when you are following a subsystem rather than a process.

Capturing a crash#

The sequence that works:

  1. Clear the buffer: adb logcat -c.
  2. Start the app or trigger the crash.
  3. Dump the crash buffer: adb logcat -b crash -d.
  4. If the app is still failing, read main around the same timestamp.

The Java stack trace names the exception and the top frames. The native crash is a tombstone, with a signal, a backtrace and a register dump. Both are worth learning to skim.

Reading events#

The events buffer is a structured log used by the platform's stats pipeline. Lines look like event_type:key=value pairs. It is not designed for human reading, but it is where things like activity launches and process starts are recorded in a parseable form.

Walkthrough#

  1. Clear and start

    adb logcat -c

    You should seeNo output from the clear command.
  2. Watch the main buffer

    adb logcat | head -40

    You should seeA stream of lines from many tags.
  3. Filter to one tag

    adb logcat ActivityManager:I *:S

    You should seeOnly ActivityManager lines at info or above.
  4. Find a process and filter to it

    adb shell pidof com.android.settings adb logcat --pid=<pid>

    You should seeThe PID of the package, then only that process's lines.
  5. Read the crash buffer

    adb logcat -b crash -d

    You should seeAn empty buffer, or recent crash entries.
logcat filters
adb logcat -c
adb logcat | head -40
adb logcat ActivityManager:I *:S
adb shell pidof com.android.settings
adb logcat --pid=<pid>
adb logcat -b crash -d
Example output
Illustrative output — PIDs, tags and content differ per device.

Challenges#

Challenge 1 — Find the launch of an app#

Start an app and find the log line that records its process start.

Reveal the answer
adb logcat -c
adb shell am start -W -n com.android.settings/.Settings
adb logcat -d | grep -i "Start proc"

The ActivityManager logs a Start proc <pid>:<package> line when it forks the process. That line is a useful anchor: everything after it in the same process is the app's startup.

Challenge 2 — Difference between -d and -c#

Explain what each does and when you would use it.

Reveal the answer

-d dumps the buffer and exits, without clearing it. -c clears the buffer. Use -c before a reproduction so the buffer only contains the interesting window; use -d to capture what is there and keep it for reading. Using -c when you meant -d destroys the evidence.

Challenge 3 — Find a warning you should care about#

Filter to warnings and errors from the system buffer and identify one that names a component you recognise.

Reveal the answer
adb logcat -b system -d '*:W'

On a healthy device there are usually a handful of warnings, most of them benign. The exercise is to read the tag and message and decide whether it names something you understand. A W from a familiar subsystem is a lead; a W from a vendor tag you have never seen is often noise.

What you learned#

You can turn a firehose into a filtered stream, choose the right buffer, and capture a crash. That is enough logcat for most debugging, and it is the foundation for the tracing labs.

Next#

Lab 5 — Memory and power moves from text to numbers.

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsAndroid Debug Bridge (adb)developer.android.comaccessed 2026-10-27↩
  2. docsdumpsysdeveloper.android.comaccessed 2026-10-27↩
  3. docsAnrdeveloper.android.comaccessed 2026-10-27↩
  4. docsProcesses and threads overview | App qualitydeveloper.android.comaccessed 2026-10-27↩