Android Debugging and Performance Analysis
Android Debugging and Performance Analysis
Performance Analysis
CC-BY-SA 3.0 - Attribution requirements and misc., PLEASE READ:
This slide must remain as-is in this specific location (slide #1), everything else you are free to change;
including the logo :-)
Use of figures in other documents must feature the below "Originals at" URL immediately under that
figure and the below copyright notice where appropriate.
You are FORBIDDEN from using the default "About" slide as-is or any of its contents.
Copyright (C) 2013-2016, Opersys inc.
These slides created by: Karim Yaghmour
Originals at: http://www.opersys.com/training/
About
Understand the set of debugging and performance monitoring tools and capabilities available in
Android
Understand the internals and limitations of each
Get hands-on experience with the tools and capabilities
Determine which ones are most appropriate, useful and/or important for a given task
Goals - Specifics
Understand the Android stack's debugging mechanisms and their internals
Debug from the app level all the way down to kernel drivers
Using Linux debugging tools with Android
Learning about Android-specific tools
Monitor performance and latencies
Quantify and analyze memory usage
Breakpoint and step through the stack
Apply commonly-used techniques for framework debugging
Familiarize with lesser-known tools and capabilities built into Android
HANDS ON
Prerequisites
C/C++
Java
Linux command line
Android internals
Linux kernel internals
Linux device drivers
ARM architecture
Topics
1. Internals Architecture Quick Recap
2. Working with the AOSP Sources
3. Classifying and Analyzing Tools
4. Kernel Tools and Capabilities
5. Android-Agnostic User-Space Tools
6. Android-Specific User-Space Tools
7. Java Tools
8. System Services Interfacing
9. Other Tools and Techniques
10. glibc User-Space
Courseware
These slides
Exercises
Online documentation
"Use the Source, Luke, use the Source. Be one with the code." -- Linus Torvalds
Hands-On Environment
Host
Ubuntu-based system
50GB / AOSP
Target
Nexus 7 2013 ("flo")
Qualcomm Snapdragon S4 Pro – APQ8064
Krait CPU, 4-core, 1.51 GHz, 2MB L2 cache
2 GB on-board DDR3 (PCDDR 533MHz)
16 GB eMMC
Combined power/usb
Internals Architecture Quick Recap
Hardware used to run Android
AOSP
Binder
System Services
HAL
Call walkthrough
System startup
Debug setup
Network boot
Symbolic debugging
1. Hardware used to run Android
2. AOSP
3. Binder
4. System Services
5. HAL
6. Call walkthrough
7. System startup
8. Debug setup
9. Network boot
10. Symbolic debugging
Working with the AOSP Sources
1. Basics
2. Preparing for Studio import
3. Importing into Studio
4. Browsing the sources
1. Basics
repo
build/envsetup.sh
godir
croot
mm
m
jgrep
cgrep
resgrep
hmm
lunch
make -j8
2. Preparing for Studio import
AOSP:
Get AOSP ... from Google or otherwise
Extract if needed
Configure, build, etc.
Android Studio:
Get Android Studio from developer.android.com
Extract
Start and update and if needed
Create AOSP project files for Studio:
[aosp]$ make idegen && development/tools/idegen/idegen.sh
Start Studio:
Choose "Open an Existing Android Studio Project"
Select android.ipr from AOSP
Let it finish indexing
Close Studio
Restart Studio
Click on "Framework Detected" bubble
4. Browsing the Sources
procfs
sysfs
configs
debugfs
dmesg/printk
1.1. procfs
Mount as /sys/kernel/debug
Free "scratch area" for all things debugging
No fixed rules of what can or has to be done
Used by ftrace
If you need to debug a driver, use this FS
Documentation/filesystems/debugfs.txt
Implemented: kernel/printk.c
Can loose data in cases of large output
Widely-used throughout kernel sources
Don't call while holding lock:
Has lock contention of its own
2. Instrumentation
mcount
tracepoints
kprobes
uprobes
HW counters
HW breakpoints
2.1. mcount
gcc-based mechanism
Trigger on -pg flag
Originally-designed for gprof
Kernel-side implemented in assembly:
arch/arm/kernel/entry-common.S
Conditional to CONFIG_FUNCTION_TRACER
Two possible behaviors -- CONFIG_DYNAMIC_FTRACE:
Hardcoded call
Dynamically-patched nop
2.2. Tracepoints
Instrument your own code, for fun and profit
In kernel:
Use built-in mechanism to define/use custom tracepoints
See
kernel/tracepoint.c
include/linux/tracepoint.h
include/trace/*
include/trace/events/* -- definition of all global static tracepoints
Documentation/trace/tracepoints.txt
SystemTap
ktap
eBPF trace
ftrace
LTTng
oprofile
perf
3.1. SystemTap
Problem:
kprobes requires hand-crafted modules, for each probe point
Need:
Higher-level mechanism for defining and handling probe points
Solution:
SystemTap
Built on kprobe mechanism
External project from the kernel (IBM, RedHat, Intel)
Effectively deprecates DProbes
Full-fledged scripting language for creating/handling probes
HUGE number of canned scripts for all sorts of uses
https://sourceware.org/systemtap/
Android support
None officially -- not in AOSP
Maybe?:
https://github.com/flipreverse/systemtap-android
Also: requires a compiler to build the modules ...
See here for a good discussion of the issues ... and a diagram:
http://omappedia.org/wiki/Systemtap#Systemtap_and_Cross_Compilation
Resources
https://sourceware.org/systemtap/wiki
https://sourceware.org/systemtap/tutorial/
https://sourceware.org/systemtap/tapsets/
3.2. ktap
Problem:
SystemTap requires a compiler
SystemTap requires loading modules
Need:
Something similar to SystemTap, minus its issues
Solution:
ktap
Compiles scripts into bytecode
Bytecode is interpreted by lua-based VM in kernel:
Seriously, it sounds scarier than it actually is
Released in May 2013
Initially positive feedback from key kernel developers
Nack'ed by Ingo Molnar
Aims to be the "DTrace" of Linux
Android support
None that I know of, this is too new at this point (Jan 2014)
Developer has embedded background so maybe ... just maybe
Makefile doesn't seem to have "CROSS_COMPILE" prefix
Resources
http://www.ktap.org/
http://events.linuxfoundation.org/sites/events/files/lcjpcojp13_zhangwei.pdf
https://github.com/ktap/ktap
https://lwn.net/Articles/531059/
3.3. eBPF
Documentation/tracing/ftrace.txt
Kernel configuration options to watch for:
CONFIG_FTRACE
CONFIG_FUNCTION_TRACER
CONFIG_FUNCTION_GRAPH_TRACER
CONFIG_STACK_TRACER
CONFIG_DYNAMIC_FTRACE
Implementation - kernel/trace/
blktrace.c trace_events.c trace_output.h
ftrace.c trace_events_filter.c trace_printk.c
Kconfig trace_events_filter_test.h trace_probe.c
Makefile trace_export.c trace_probe.h
power-traces.c trace_functions.c trace_sched_switch.c
ring_buffer_benchmark.c trace_functions_graph.c trace_sched_wakeup.c
ring_buffer.c trace.h trace_selftest.c
rpm-traces.c trace_irqsoff.c trace_selftest_dynamic.c
trace_branch.c trace_kdb.c trace_stack.c
trace.c trace_kprobe.c trace_stat.c
trace_clock.c trace_mmiotrace.c trace_stat.h
trace_entries.h trace_nop.c trace_syscalls.c
trace_event_perf.c trace_output.c trace_uprobe.c
Check if tracing is on:
# cat tracing_on
0
Clear a trace:
# echo > trace
Restart tracing:
# echo 1 > tracing_on
Check graph tracer output:
# cat trace
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
0) 0.000 us | } /* __sync_icache_dcache */
0) 0.000 us | __sync_icache_dcache();
0) 0.000 us | vm_normal_page();
0) 0.000 us | __sync_icache_dcache();
0) 0.000 us | _cond_resched();
0) 0.000 us | } /* copy_pte_range */
0) 0.000 us | } /* copy_page_range */
0) | cap_vm_enough_memory() {
0) 0.000 us | cap_capable();
0) 0.000 us | __vm_enough_memory();
0) 0.000 us | }
0) 0.000 us | kmem_cache_alloc();
0) | anon_vma_fork() {
0) | anon_vma_clone() {
0) 0.000 us | kmem_cache_alloc();
0) 0.000 us | mutex_lock();
0) 0.000 us | anon_vma_chain_link();
0) 0.000 us | mutex_unlock();
0) 0.000 us | }
...
Linux toolset
trace-cmd (uses splice())-- not avail. in Android
http://git.kernel.org/cgit/linux/kernel/git/rostedt/trace-cmd.git
KernelShark -- not avail. in Android
http://people.redhat.com/srostedt/kernelshark/HTML/
Neither of these are included in the AOSP
Support in Android
Since 4.1 -- significant changes in 4.2
... finicky ...
Android stack feeds events into ftrace
Same entries in /sys/kernel/debug/tracing
Neither trace-cmd nor KernelShark
Android tools:
On the device: atrace -- native binary
On the host: systrace -- Python script
systrace calls atrace over adb
systrace-generated traces viewable w/ Chrome
And nothing but Chrome ... NIH?
# atrace --help
usage: atrace [options] [categories...]
options include:
-a appname enable app-level tracing for a comma separated list of cmdlines
-b N use a trace buffer size of N KB
-c trace into a circular buffer
-k fname,... trace the listed kernel functions
-n ignore signals
-s N sleep for N seconds before tracing [default 0]
-t N trace for N seconds [defualt 5]
-z compress the trace dump
--async_start start circular trace and return immediatly
--async_dump dump the current contents of circular trace buffer
--async_stop stop tracing and dump the current contents of circular
trace buffer
--list_categories
list the available tracing categories
root@flo:/ # atrace --list_categories
gfx - Graphics
input - Input
view - View System
webview - WebView
wm - Window Manager
am - Activity Manager
sm - Sync Manager
audio - Audio
video - Video
camera - Camera
hal - Hardware Modules
app - Application
res - Resource Loading
dalvik - Dalvik VM
rs - RenderScript
bionic - Bionic C Library
power - Power Management
sched - CPU Scheduling
irq - IRQ Events
freq - CPU Frequency
idle - CPU Idle
disk - Disk I/O
load - CPU Load
sync - Synchronization
workq - Kernel Workqueues
memreclaim - Kernel Memory Reclaim
regulators - Voltage and Current Regulators
Google's doc:
https://developer.android.com/tools/help/systrace.html
https://developer.android.com/tools/debugging/systrace.html
Also have a look at these:
/external/chromium-trace/systrace.py
/frameworks/native/cmds/atrace
/frameworks/base/core/java/android/os/Trace.java
/frameworks/base/core/jni/android_os_Trace.cpp
/frameworks/native/include/utils/Trace.h
/system/core/include/cutils/trace.h
/system/core/libcutils/trace.c
/frameworks/native/libs/utils/Trace.cpp
Look for:
ATRACE* in c/cpp files
Trace.traceBegin()/trace.traceEnd() in Java files
Use in C files in 4.4:
#define ATRACE_TAG ATRACE_TAG_ALWAYS
...
#include <cutils/trace.h>
...
fct() {
...
ATRACE_BEGIN()
...
ATRACE_END()
...
}
opcontrol: usage:
--list-events list event types
--help this message
--verbose show extra status
--verbose-log=lvl set daemon logging verbosity during setup
levels are: all,sfile,arcs,samples,module,misc
--setup setup directories
...
Requires CONFIG_PERF_EVENTS
Unlike ftrace, really can't be used without perf command
# perf
rNNN (see 'perf list --help' on how to encode it) [Raw hardware event descriptor]
Annotating:
$ perfhost annotate --symfs out/target/product/flo/symbols
# Events: 15K cycles
#
# Overhead Command Shared Object ... Symbol
# ........ ............... ............................... ....................................
#
61.17% adbd [unknown] [k] 0xc07c5cd4
5.19% adbd dumpsys [.] 0x1b8f8
4.52% perf [unknown] [k] 0xc07c3fe0
3.46% swapper [unknown] [k] 0xc07c5d0c
2.71% logcat [unknown] [k] 0xc029b0d0
2.57% kworker/0:0 [unknown] [k] 0xc07c5cd4
1.76% mpdecision [unknown] [k] 0xc029a77c
1.53% system_server dumpsys [.] 0x3c18c
1.39% system_server [unknown] [k] 0xc0087710
0.63% ls [unknown] [k] 0xc0008578
0.51% perf dumpsys [.] 0x25fc8
0.41% ndroid.launcher dumpsys [.] _Z17dvmHeapBitmapWalkPK10HeapBitmapPFvP6ObjectPvES4_
0.39% d.process.media dumpsys [.] 0x39c18
0.39% system_server dumpsys [.] 0x81740
0.37% system_server dumpsys [.] 0x5226
0.36% logcat dumpsys [.] 0x18f4
0.36% system_server dumpsys [.] dvmAsmInstructionStart
0.32% ps [unknown] [k] 0xc07c7940
0.28% perf dumpsys [.] dlfree
0.27% ndroid.launcher [unknown] [k] 0xc07c58d4
0.27% perf dumpsys [.] memcpy
...
Support in Android
perf tools in external/linux-tools-perf
Will build only if $TARGET_BUILD_VARIANT=eng
Otherwise the binary won't be in the AOSP
Works the same as on the Linux command line
perf.data files are automatically stored into /data/
Annotation requires copying the perf.data file to the host
external/linux-tools-perf/ already patched to use cross-dev objdump
4. Debugging
kgdb/kdb
Other kernel debugging mechanisms
JTAG
4.1. kgdb/kdb
Crash dumps
kexec new kernel to dump-capture failed kernel
x86- and big-iron-centric
Documentation/kdump/kdump.txt
Oops messages
Kernel errors/exceptions reported to dmesg
Documentation/oops-tracing.txt
Dynamic debug
Dynamically-enable in-kernel debug info
Documentation/dynamic-debug-howto.txt
4.3. JTAG
True geeks use JTAG debuggers
See what the SoC is really doing
Several vendors out there: Lauterbach, Abatron, ...
Typically N*$1,000, where N > 2
Open source: Flyswater 2 (HW) + OpenOCD (SW)
Use/operation JTAG-vendor specific
Typical:
gdb-based
Setup file to prep processor for debug
Need vmlinux file
Module debugging requires relocation info
Android-Agnostic User-Space Tools
strace
ltrace
LTTng UST
apitrace
gdb/gdbserver
5.1. strace
$ gdbclient system_server
[1] 13531
Attached; pid = 1653
Listening on port 5039
GNU gdb (GDB) 7.6
...
Reading symbols from /media/6921e18a-5b32-4fe8-97cc-62a85a6f351f/home/karim/opersys-dev/android/aosp-5.0.2_r1-pristine/out/ta
Remote debugging from host 127.0.0.1
warning: while parsing target library list: not well-formed (invalid token)
warning: Could not load shared library symbols for 29 libraries, e.g. 'U.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
readv () at bionic/libc/arch-arm/syscalls/readv.S:12
12 neg r0, r0
Function "art_sigsegv_fault" not defined.
Breakpoint 1 (art_sigsegv_fault) pending.
ART debugging mode is enabled.
If you are debugging a native only process, you need to
re-enable normal SIGSEGV handling using this command:
handle SIGSEGV print stop
(gdb) b com_android_server_power_PowerManagerService.cpp:126
Breakpoint 2 at 0xb404f404: file frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp, line 126
(gdb) cont
Continuing.
[New Thread 30562]
[Switching to Thread 30562]
Sort options:
-v Sort processes by VSS.
-r Sort processes by RSS.
-p Sort processes by PSS.
-u Sort processes by USS.
(Default sort order is PSS.)
-P /path Limit libraries displayed to those in path.
-R Reverse sort order (default is descending).
-h Display this help screen.
RSStot VSS RSS PSS USS Name/PID
55386K /dev/ashmem/dalvik-heap
29340K 29340K 23506K 23272K com.android.systemui [645]
13680K 13680K 7753K 7516K com.android.launcher [765]
11240K 11240K 5406K 5172K system_server [565]
7664K 7664K 1628K 1384K com.android.phone [737]
7552K 7552K 1521K 1280K android.process.media [692]
7392K 7392K 1326K 1076K android.process.acore [818]
7228K 7228K 1184K 940K com.android.inputmethod.latin [710]
7108K 7108K 1031K 784K com.android.email [1091]
...
40517K anon_inode:dmabuf
39972K 39972K 25758K 11544K /system/bin/surfaceflinger [253]
16172K 16172K 8142K 132K system_server [565]
11884K 11884K 5944K 4K com.android.launcher [765]
964K 964K 673K 408K com.android.systemui [645]
408K 0K 0K 0K /system/bin/mediaserver [256]
40K 0K 0K 0K /system/bin/qseecomd [341]
19489K /dev/ashmem/dalvik-aux-structure
1480K 1456K 1194K 1184K system_server [565]
1812K 1740K 1116K 1088K com.android.email [1091]
1628K 1552K 1087K 1068K com.android.phone [737]
1824K 1740K 1076K 1044K com.android.contacts [904]
1656K 1572K 1050K 1028K android.process.media [692]
1760K 1684K 982K 944K com.android.settings [801]
...
6.5. procmem
Report:
realtime
uptime
awake percentage
sleep percentage
# timeinfo
986408 986416 100 0
6.9. Logger / logcat
Usage: logcat [options] [filterspecs]
options include:
-s Set default filter to silent.
Like specifying filterspec '*:s'
-f <filename> Log to file. Default to stdout
-r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f
-n <count> Sets max number of rotated logs to <count>, default 4
-v <format> Sets the log print format, where <format> is one of:
stack:
bed419f0 00000000
bed419f4 00000000
bed419f8 00000000
...
6.12. debuggerd
Raw Dalvik VM
Can't run Android code
Seldom used
# dalvikvm -help
Monitor/Studio integration
Starting debug with Studio
Debugging
Debugging multiple processes
7.7.1. Monitor/Studio integration
Start Studio
Start Monitor ("Android" icon on toolbar)
Each process has a separate host-side socket
Select the process you want to debug:
It'll get port 8700
Go back to Studio:
Run->Edit Configurations->"+"
Remote->Port: 8700
Apply & Debug
Go back to Monitor:
Check that the little green bug is beside your process
You're now ready to debug
7.7.2. Multiple processes
In-app instrumentation
Tools to view traces;
traceview
dmtracedump
Reference
https://developer.android.com/tools/debugging/debugging-tracing.html
7.10. Memory usage analysis
Two tools:
Android Device Monitor
Android Monitor (NOT the same thing)
Eclipse Memory Analyzer (MAT)
References:
http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html
http://www.vogella.com/tutorials/EclipseMemoryAnalyzer/article.html
http://www.eclipse.org/mat/
System Services Interfacing
dumpsys
service (espc. “service call” and aidl files)
am
pm
wm
svc
monkey
ANR dumps
8.1. dumpsys
C-based tool
8.2. service
See system service's aidl file to get "CODE" and parameter list
C-based tool
8.3. am
Interact with the Activity Manager
Allows you to send intents on the command line (very powerful)
# am
usage: am [subcommand] [options]
usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]
[--R COUNT] [-S] [--opengl-trace] <INTENT>
am startservice <INTENT>
am force-stop <PACKAGE>
am kill <PACKAGE>
am kill-all
am broadcast <INTENT>
am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]
[--no-window-animation] <COMPONENT>
am profile start <PROCESS> <FILE>
am profile stop [<PROCESS>]
am dumpheap [flags] <PROCESS> <FILE>
...
8.4. pm
Interact with Package Manager
usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [FILTER]
pm list permission-groups
pm list permissions [-g] [-f] [-d] [-u] [GROUP]
pm list instrumentation [-f] [TARGET-PACKAGE]
pm list features
pm list libraries
pm path PACKAGE
pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]
[--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH
pm uninstall [-k] PACKAGE
pm clear PACKAGE
pm enable PACKAGE_OR_COMPONENT
8.5. wm
Interact with UI
Can take scripts
usage: monkey [-p ALLOWED_PACKAGE [-p ALLOWED_PACKAGE] ...]
[-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]
[--ignore-crashes] [--ignore-timeouts]
[--ignore-security-exceptions]
[--monitor-native-crashes] [--ignore-native-crashes]
[--kill-process-after-error] [--hprof]
[--pct-touch PERCENT] [--pct-motion PERCENT]
[--pct-trackball PERCENT] [--pct-syskeys PERCENT]
[--pct-nav PERCENT] [--pct-majornav PERCENT]
[--pct-appswitch PERCENT] [--pct-flip PERCENT]
[--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]
[--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]
8.8. ANR dumps
karim.yaghmour@opersys.com