Skip to content

How to Debug Android Apps with Logcat and ADB: A Complete Guide for Developers

Purpose

In this post, I will demonstrate how to debug Android apps using logcat and adb command-line tools. These skills are essential for mid-level Android developers, yet many developers skip them because modern courses focus heavily on UI development and IDE features.

The Problem

When I was preparing for a mid-level Android developer interview, I thought I was ready. I knew Jetpack Compose, understood MVVM architecture, and could build complex UIs. But then the interviewer asked: “How do you debug a crash on a remote device using logcat?”

I froze.

Interview realization
Interviewer: "How would you debug an ANR issue on a production device?"
Me: "I... I usually use Android Studio's debugger and breakpoints..."
Interviewer: "What if you can't access the device directly? What if it's a user-reported crash?"
Me: "I'm not sure..."

This gap in knowledge isn’t just my problem. In a Reddit discussion about learning Android properly, the original poster revealed they lacked “debugging with logcat/adb” skills during interviews. Modern Android courses and bootcamps focus on UI development and architecture patterns while neglecting essential debugging skills.

Environment

  • Android SDK Platform Tools (adb)
  • Terminal/Command Line
  • Physical Android device or emulator
  • Basic familiarity with Android logging

Essential ADB Commands for Debugging

Basic Logcat Commands

Let me start with the fundamental commands:

Basic logcat commands
# Start logging - basic command
adb logcat
# Clear previous logs before starting fresh
adb logcat -c
# Write logs to file for later analysis
adb logcat > debug_log.txt
# Log from specific device (when multiple connected)
adb -s device_id logcat

When I first ran adb logcat, I was overwhelmed by thousands of log messages scrolling past. This is the first mistake many developers make - not filtering the output.

Filtering by Priority Level

Android uses priority levels for logs. Understanding these is crucial:

Filter by priority level
# Show only errors
adb logcat *:E
# Show errors and warnings
adb logcat *:W
# Show everything (verbose - default)
adb logcat *:V
Priority levels (lowest to highest)
V - Verbose (detailed flow tracing)
D - Debug (development debugging)
I - Info (important events)
W - Warning (potential issues)
E - Error (actual errors)
F - Fatal (crashes)
S - Silent (suppress all)

Filtering by Tag

Tags help identify where logs come from. When I debug my app, I use specific tags:

Filter by tag
# Show logs from specific tag only
adb logcat -s MyTag
# Multiple tags with different levels
adb logcat MyTag:D OtherTag:E
# Exclude specific tags (using grep)
adb logcat | grep -v "ExcludedTag"

Advanced Formatting Options

Formatting affects how much information you see:

Format options
# Show timestamps
adb logcat -v time
# Brief format (default)
adb logcat -v brief
# Long format with process/thread info
adb logcat -v long
# Threadtime format (best for debugging race conditions)
adb logcat -v threadtime

The -v threadtime format is particularly useful for debugging threading issues because it shows when each log was created and which thread produced it.

Filtering by Package/Application

The most useful command I use daily filters logs to just my app:

Filter by package
# Get your app's PID first
adb shell pidof com.example.myapp
# Filter by PID
adb logcat --pid=12345
# Or combine in one command
adb logcat --pid=$(adb shell pidof -s com.example.myapp)

Real-World Debugging Scenarios

Scenario 1: Debugging App Crashes

When my app crashes, I use this workflow:

Crash debugging
# Clear old logs first
adb logcat -c
# Reproduce the crash, then check logs
adb logcat -d | grep -E "FATAL|AndroidRuntime" -A 20

The -d flag dumps the current log buffer and exits, which is useful for capturing logs after a crash.

Scenario 2: Monitoring Network Requests

Network debugging
# Monitor network requests
adb logcat | grep -E "OkHttp|Retrofit|Network"

Scenario 3: Tracking Memory Issues

Memory debugging
# Track memory issues
adb logcat | grep -E "GC_|OutOfMemory|leak"

Scenario 4: Watching for ANR (Application Not Responding)

ANR detection
# Watch for ANR
adb logcat | grep "ANR"
# Or get detailed ANR info
adb logcat -v time | grep -E "ANR|InputDispatching"

ADB Shell Debugging Commands

Beyond logcat, adb provides powerful shell commands:

ADB shell commands
# List installed packages
adb shell pm list packages
# Check package info
adb shell dumpsys package com.example.myapp
# Monitor memory usage
adb shell dumpsys meminfo com.example.myapp
# Check CPU usage
adb shell dumpsys cpuinfo
# View process details
adb shell ps -A | grep myapp
# Take a bug report (comprehensive system state)
adb bugreport > bug_report.zip

The dumpsys meminfo command is invaluable for detecting memory leaks in your app.

Logging Best Practices in Your App

The quality of your logs determines how easily you can debug. Here’s how I structure logging:

Logging best practices
// Use appropriate log levels
Log.v("LoginActivity", "Verbose: button clicked") // Only in development
Log.d("LoginActivity", "Debug: username=$username") // Development debugging
Log.i("LoginActivity", "Info: user logged in successfully") // Important events
Log.w("LoginActivity", "Warning: deprecated API used") // Potential issues
Log.e("LoginActivity", "Error: ${e.message}", e) // Actual errors with stack trace
Build configuration for log stripping
// In build.gradle
buildTypes {
release {
minifyEnabled true
// ProGuard rules to remove Log.d and Log.v calls
}
}

Quick Reference - Most Useful Commands

Here are the commands I use most frequently:

Quick reference commands
# 1. Debug specific app (most common use case)
adb logcat --pid=$(adb shell pidof -s com.example.myapp) -v time
# 2. Show all errors across the system
adb logcat *:E -v time
# 3. Search for crashes in recent logs
adb logcat -d | grep -E "FATAL|AndroidRuntime"
# 4. Monitor specific functionality
adb logcat -v time | grep -E "MyApp|OkHttp|Retrofit"
# 5. Save logs for later analysis
adb logcat -v time > $(date +%Y%m%d_%H%M%S)_debug.log

Creating Debugging Aliases

I’ve added these aliases to my shell configuration for quick access:

Shell aliases for debugging
# Add to ~/.bashrc or ~/.zshrc
# Quick app debug
alias logapp='adb logcat --pid=$(adb shell pidof -s com.example.myapp) -v time'
# Error watch
alias logerr='adb logcat *:E -v time'
# Crash finder
alias findcrash='adb logcat -d | grep -E "FATAL|AndroidRuntime" -A 20'
# Clear and watch
alias logclear='adb logcat -c && adb logcat -v time'

Common Mistakes to Avoid

Mistake 1: Only Using Android Studio’s Logcat Panel

The GUI panel is convenient but hides the power of command-line filtering. Practice command-line logcat regularly.

Mistake 2: Not Filtering Logs

Running adb logcat without filters dumps thousands of messages. Always use filters (-s, *:E, --pid, or grep).

Mistake 3: Using Verbose Logging in Production

Verbose logging impacts performance and can leak sensitive data. Strip debug logs in release builds.

Mistake 4: Ignoring Timestamps and Thread Information

Use -v threadtime for debugging threading issues and understanding event sequences.

Mistake 5: Not Clearing Logs Before Reproducing Issues

Always run adb logcat -c before reproducing a bug to avoid searching through stale logs.

Why This Matters

Understanding logcat and adb debugging transforms you from a developer who relies solely on IDE features to one who can diagnose issues anywhere - from local development to production crashes on remote devices.

Career Impact: As the Reddit discussion highlights, logcat and adb debugging are expected skills for mid-level Android developers. Not knowing these tools can cost you job opportunities.

Production Debugging: When your app crashes on a user’s device, you won’t have access to Android Studio’s debugger. Command-line tools become essential.

Development Speed: Filtering logs to relevant information dramatically speeds up debugging compared to searching through thousands of lines in Android Studio’s Logcat panel.

Summary

In this post, I demonstrated how to debug Android apps using logcat and adb command-line tools. The key points are:

  1. Use adb logcat --pid=<package> to isolate your app’s logs
  2. Filter by priority level (*:E, *:W) to reduce noise
  3. Use -v threadtime for debugging threading issues
  4. Always clear logs (adb logcat -c) before reproducing bugs
  5. Learn to combine logcat with grep for powerful searching
  6. Practice these commands regularly - they’re expected knowledge for mid-level roles

Start by incorporating one or two logcat commands into your daily workflow. Use adb logcat --pid instead of the Logcat panel. Filter by error level when investigating crashes. Pretty soon, these commands will become second nature, and you’ll wonder how you ever debugged without them.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments