blob: ad8c34a5789f61efd03878127dc0e0afa80d1285 [file] [log] [blame] [view]
# Android Debugging Instructions
Chrome on Android has java and c/c++ code. Each "side" have its own set of tools
for debugging. Here's some tips.
## Launching
You can run the app by using one of the wrappers.
# Installs, launches, and enters logcat.
out/Default/bin/content_shell_apk run --args='--disable-fre' 'data:text/html;utf-8,<html>Hello World!</html>'
# Launches without first installing. Does not show logcat.
out/Default/bin/chrome_public_apk launch --args='--disable-fre' 'data:text/html;utf-8,<html>Hello World!</html>'
## Logging
[Chromium logging from LOG(INFO)](
etc., is directed to the Android logcat logging facility. You can filter the
messages, e.g. view chromium verbose logging, everything else at warning level
# Shows a coloured & filtered logcat.
out/Default/bin/chrome_public_apk logcat [-v] # Use -v to show logs for other processes
### Warnings for Blink developers
* **Do not use fprintf or printf debugging!** This does not
redirect to logcat.
* Redirecting stdio to logcat, as documented
has a bad side-effect that it breaks ``. See
[here for details](
## Take a Screenshot
build/android/ /tmp/screenshot.png
## Inspecting the View Hierarchy
Generate an [Android Studio]( project, and then use
[Layout Inspector](
## Debugging Java
For both apk and test targets, pass `--wait-for-java-debugger` to the wrapper
# Install, launch, and wait:
out/Default/bin/chrome_public_apk run --wait-for-java-debugger
# Launch, and have GPU process wait rather than Browser process:
out/Default/bin/chrome_public_apk launch --wait-for-java-debugger --debug-process-name privileged_process0
# Have Renderers wait:
out/Default/bin/chrome_public_apk launch --args="--renderer-wait-for-java-debugger"
# Have tests wait:
out/Default/bin/run_chrome_public_test_apk --wait-for-java-debugger
out/Default/bin/run_chrome_junit_tests --wait-for-java-debugger # Specify custom port via --debug-socket=9999
### Android Studio
* Open Android Studio ([instructions](
* Click "Run"->"Attach debugger to Android process" (see
[here]( for more).
* Click "Run"->"Attach to Local Process..." for Robolectric junit tests.
### Eclipse
* In Eclipse, make a debug configuration of type "Remote Java Application".
Choose a "Name" and set "Port" to `8700`.
* Make sure Eclipse Preferences > Run/Debug > Launching > "Build (if required)
before launching" is unchecked.
* Run Android Device Monitor:
* Now select the process you want to debug in Device Monitor (the port column
should now mention 8700 or xxxx/8700).
* Run your debug configuration, and switch to the Debug perspective.
## Debugging C/C++
While the app is running, use the wrapper script's `gdb` command to enter into a
gdb shell.
When running with gdb attached, the app runs **extremely slowly**.
# Attaches to browser process.
out/Default/bin/content_shell_apk gdb
out/Default/bin/chrome_public_apk gdb
# Attaches to gpu process.
out/Default/bin/chrome_public_apk gdb --debug-process-name privileged_process0
# Attach to other processes ("chrome_public_apk ps" to show pids).
out/Default/bin/chrome_public_apk gdb --pid $PID
When connecting, gdb will complain of not being able to load a lot of libraries.
This happens because of java code. The following messages are all expected:
Connecting to :5039...
warning: Could not load shared library symbols for 211 libraries, e.g. /system/framework/arm/boot.oat.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Failed to read a valid object file image from memory.
### Using Visual Studio Code
While the app is running, run the `gdb` command with `--ide`:
out/Default/bin/content_shell_apk gdb --ide
Once the script has done its thing (generally ~1 second after the initial
time its used), open []( and ensure you have the
[Android launch entry](
Connect via the IDE's launch entry. Connecting takes 30-40 seconds.
When troubleshooting, it's helpful to enable
[engine logging](
Known Issues:
* Pretty printers are not working properly.
### Waiting for Debugger on Early Startup
# Install, launch, and wait:
out/Default/bin/chrome_public_apk run --args="--wait-for-debugger"
# Launch, and have GPU process wait rather than Browser process:
out/Default/bin/chrome_public_apk launch --args="--wait-for-debugger-children=gpu-process"
# Or for renderers:
out/Default/bin/chrome_public_apk launch --args="--wait-for-debugger-children=renderer"
#### With an IDE
Once `gdb` attaches, the app will resume execution, so you must set your
breakpoint before attaching.
#### With Command-line GDB
Once attached, gdb will drop into a prompt. Set your breakpoints and run "c" to
## Symbolizing Crash Stacks and Tombstones (C++)
If a crash has generated a tombstone in your device, use:
build/android/ --output-directory out/Default
If you have a stack trace (from `adb logcat`) that needs to be symbolized, copy
it into a text file and symbolize with the following command (run from
third_party/android_platform/development/scripts/stack --output-directory out/Default [tombstone file | dump file]
`stack` can also take its input from `stdin`:
adb logcat -d | third_party/android_platform/development/scripts/stack --output-directory out/Default
third_party/android_platform/development/scripts/stack --output-directory out/Default ~/crashlogs/tombstone_07-build231.txt
## Deobfuscating Stack Traces (Java)
You will need the ProGuard mapping file that was generated when the application
that crashed was built. When building locally, these are found in:
Build the `java_deobfuscate` tool:
ninja -C out/Default java_deobfuscate
Then run it via:
# For a file:
out/Default/bin/java_deobfuscate PROGUARD_MAPPING_FILE.mapping < FILE
# For logcat:
adb logcat | out/Default/bin/java_deobfuscate PROGUARD_MAPPING_FILE.mapping
## Get WebKit code to output to the adb log
In your build environment:
adb root
adb shell stop
adb shell setprop log.redirect-stdio true
adb shell start
In the source itself, use `fprintf(stderr, "message");` whenever you need to
output a message.
## Debug unit tests with GDB
To run unit tests use the following command:
out/Debug/bin/run_test_name -f <test_filter_if_any> --wait-for-debugger -t 6000
That command will cause the test process to wait until a debugger is attached.
To attach a debugger:
build/android/adb_gdb --output-directory=out/Default --package-name=org.chromium.native_test
After attaching gdb to the process you can use it normally. For example:
(gdb) break main
Breakpoint 1 at 0x9750793c: main. (2 locations)
(gdb) continue