xref: /aosp_15_r20/system/extras/simpleperf/doc/debug_dwarf_unwinding.md (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker# Debug dwarf unwinding
2*288bf522SAndroid Build Coastguard Worker
3*288bf522SAndroid Build Coastguard WorkerDwarf unwinding is the default way of getting call graphs in simpleperf. In this process,
4*288bf522SAndroid Build Coastguard Workersimpleperf asks the kernel to add stack and register data to each sample. Then it uses
5*288bf522SAndroid Build Coastguard Worker[libunwindstack](https://cs.android.com/android/platform/superproject/+/main:system/unwinding/libunwindstack/)
6*288bf522SAndroid Build Coastguard Workerto unwind the call stack. libunwindstack uses dwarf sections (like .debug_frame or .eh_frame) in
7*288bf522SAndroid Build Coastguard Workerelf files to know how to unwind the stack.
8*288bf522SAndroid Build Coastguard Worker
9*288bf522SAndroid Build Coastguard WorkerBy default, `simpleperf record` unwinds a sample before saving it to disk, to reduce space consumed
10*288bf522SAndroid Build Coastguard Workerby stack data. But this behavior makes it harder to reproduce unwinding problems. So we added
11*288bf522SAndroid Build Coastguard Workerdebug-unwind command, to help debug and profile dwarf unwinding. Below are two use cases.
12*288bf522SAndroid Build Coastguard Worker
13*288bf522SAndroid Build Coastguard Worker[TOC]
14*288bf522SAndroid Build Coastguard Worker
15*288bf522SAndroid Build Coastguard Worker## Debug failed unwinding cases
16*288bf522SAndroid Build Coastguard Worker
17*288bf522SAndroid Build Coastguard WorkerUnwinding a sample can fail for different reasons: not enough stack or register data, unknown
18*288bf522SAndroid Build Coastguard Workerthread maps, no dwarf info, bugs in code, etc. And to fix them, we need to get error details
19*288bf522SAndroid Build Coastguard Workerand be able to reproduce them. simpleperf record cmd has two options for this:
20*288bf522SAndroid Build Coastguard Worker`--keep-failed-unwinding-result` keeps error code for failed unwinding samples. It's lightweight
21*288bf522SAndroid Build Coastguard Workerand gives us a brief idea why unwinding stops.
22*288bf522SAndroid Build Coastguard Worker`--keep-failed-unwinding-debug-info` keeps stack and register data for failed unwinding samples. It
23*288bf522SAndroid Build Coastguard Workercan be used to reproduce the unwinding process given proper elf files. Below is an example.
24*288bf522SAndroid Build Coastguard Worker
25*288bf522SAndroid Build Coastguard Worker```sh
26*288bf522SAndroid Build Coastguard Worker# Run record cmd and keep failed unwinding debug info.
27*288bf522SAndroid Build Coastguard Worker$ simpleperf64 record --app com.example.android.displayingbitmaps -g --duration 10 \
28*288bf522SAndroid Build Coastguard Worker    --keep-failed-unwinding-debug-info
29*288bf522SAndroid Build Coastguard Worker...
30*288bf522SAndroid Build Coastguard Workersimpleperf I cmd_record.cpp:762] Samples recorded: 22026. Samples lost: 0.
31*288bf522SAndroid Build Coastguard Worker
32*288bf522SAndroid Build Coastguard Worker# Generate a text report containing failed unwinding cases.
33*288bf522SAndroid Build Coastguard Worker$ simpleperf debug-unwind --generate-report -o report.txt
34*288bf522SAndroid Build Coastguard Worker
35*288bf522SAndroid Build Coastguard Worker# Pull report.txt on host and show it using debug_unwind_reporter.py.
36*288bf522SAndroid Build Coastguard Worker# Show summary.
37*288bf522SAndroid Build Coastguard Worker$ debug_unwind_reporter.py -i report.txt --summary
38*288bf522SAndroid Build Coastguard Worker# Show summary of samples failed at a symbol.
39*288bf522SAndroid Build Coastguard Worker$ debug_unwind_reporter.py -i report.txt --summary --include-end-symbol SocketInputStream_socketRead0
40*288bf522SAndroid Build Coastguard Worker# Show details of samples failed at a symbol.
41*288bf522SAndroid Build Coastguard Worker$ debug_unwind_reporter.py -i report.txt --include-end-symbol SocketInputStream_socketRead0
42*288bf522SAndroid Build Coastguard Worker
43*288bf522SAndroid Build Coastguard Worker# Reproduce unwinding a failed case.
44*288bf522SAndroid Build Coastguard Worker$ simpleperf debug-unwind --unwind-sample --sample-time 256666343213301
45*288bf522SAndroid Build Coastguard Worker
46*288bf522SAndroid Build Coastguard Worker# Generate a test file containing a failed case and elf files for debugging it.
47*288bf522SAndroid Build Coastguard Worker$ simpleperf debug-unwind --generate-test-file --sample-time 256666343213301 --keep-binaries-in-test-file \
48*288bf522SAndroid Build Coastguard Worker    /apex/com.android.runtime/lib64/bionic/libc.so,/apex/com.android.art/lib64/libopenjdk.so -o test.data
49*288bf522SAndroid Build Coastguard Worker```
50*288bf522SAndroid Build Coastguard Worker
51*288bf522SAndroid Build Coastguard Worker## Profile unwinding process
52*288bf522SAndroid Build Coastguard Worker
53*288bf522SAndroid Build Coastguard WorkerWe can also record samples without unwinding them. Then we can use debug-unwind cmd to unwind the
54*288bf522SAndroid Build Coastguard Workersamples after recording. Below is an example.
55*288bf522SAndroid Build Coastguard Worker
56*288bf522SAndroid Build Coastguard Worker```sh
57*288bf522SAndroid Build Coastguard Worker# Record samples without unwinding them.
58*288bf522SAndroid Build Coastguard Worker$ simpleperf record --app com.example.android.displayingbitmaps -g --duration 10 \
59*288bf522SAndroid Build Coastguard Worker    --no-unwind
60*288bf522SAndroid Build Coastguard Worker...
61*288bf522SAndroid Build Coastguard Workersimpleperf I cmd_record.cpp:762] Samples recorded: 9923. Samples lost: 0.
62*288bf522SAndroid Build Coastguard Worker
63*288bf522SAndroid Build Coastguard Worker# Use debug-unwind cmd to unwind samples.
64*288bf522SAndroid Build Coastguard Worker$ simpleperf debug-unwind --unwind-sample
65*288bf522SAndroid Build Coastguard Worker```
66*288bf522SAndroid Build Coastguard Worker
67*288bf522SAndroid Build Coastguard WorkerWe can profile the unwinding process, get hot functions for improvement.
68*288bf522SAndroid Build Coastguard Worker
69*288bf522SAndroid Build Coastguard Worker```sh
70*288bf522SAndroid Build Coastguard Worker# Profile debug-unwind cmd.
71*288bf522SAndroid Build Coastguard Worker$ simpleperf record -g -o perf_unwind.data simpleperf debug-unwind --unwind-sample --skip-sample-print
72*288bf522SAndroid Build Coastguard Worker
73*288bf522SAndroid Build Coastguard Worker# Then pull perf_unwind.data and report it.
74*288bf522SAndroid Build Coastguard Worker$ report_html.py -i perf_unwind.data
75*288bf522SAndroid Build Coastguard Worker
76*288bf522SAndroid Build Coastguard Worker# We can also add source code annotation in report.html.
77*288bf522SAndroid Build Coastguard Worker$ binary_cache_builder.py -i perf_unwind.data -lib <path to aosp-main>/out/target/product/<device-name>/symbols/system
78*288bf522SAndroid Build Coastguard Worker$ report_html.py -i perf_unwind.data --add_source_code --source_dirs <path to aosp-main>/system/
79*288bf522SAndroid Build Coastguard Worker```
80