You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
10 KiB
257 lines
10 KiB
# Scripts reference
|
|
|
|
## Table of Contents
|
|
|
|
- [Scripts reference](#scripts-reference)
|
|
- [Table of Contents](#table-of-contents)
|
|
- [app_profiler.py](#appprofilerpy)
|
|
- [Profile from launch of an application](#profile-from-launch-of-an-application)
|
|
- [api_profiler.py](#apiprofilerpy)
|
|
- [run_simpleperf_without_usb_connection.py](#runsimpleperfwithoutusbconnectionpy)
|
|
- [binary_cache_builder.py](#binarycachebuilderpy)
|
|
- [run_simpleperf_on_device.py](#runsimpleperfondevicepy)
|
|
- [report.py](#reportpy)
|
|
- [report_html.py](#reporthtmlpy)
|
|
- [inferno](#inferno)
|
|
- [purgatorio](#purgatorio)
|
|
- [pprof_proto_generator.py](#pprofprotogeneratorpy)
|
|
- [report_sample.py](#reportsamplepy)
|
|
- [simpleperf_report_lib.py](#simpleperfreportlibpy)
|
|
|
|
|
|
## app_profiler.py
|
|
|
|
app_profiler.py is used to record profiling data for Android applications and native executables.
|
|
|
|
```sh
|
|
# Record an Android application.
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
|
|
|
|
# Record an Android application with Java code compiled into native instructions.
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative --compile_java_code
|
|
|
|
# Record the launch of an Activity of an Android application.
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity
|
|
|
|
# Record a native process.
|
|
$ python app_profiler.py -np surfaceflinger
|
|
|
|
# Record a native process given its pid.
|
|
$ python app_profiler.py --pid 11324
|
|
|
|
# Record a command.
|
|
$ python app_profiler.py -cmd \
|
|
"dex2oat --dex-file=/data/local/tmp/app-profiling.apk --oat-file=/data/local/tmp/a.oat"
|
|
|
|
# Record an Android application, and use -r to send custom options to the record command.
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
|
|
-r "-e cpu-clock -g --duration 30"
|
|
|
|
# Record both on CPU time and off CPU time.
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
|
|
-r "-e task-clock -g -f 1000 --duration 10 --trace-offcpu"
|
|
|
|
# Save profiling data in a custom file (like perf_custom.data) instead of perf.data.
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -o perf_custom.data
|
|
```
|
|
|
|
### Profile from launch of an application
|
|
|
|
Sometimes we want to profile the launch-time of an application. To support this, we added --app in
|
|
the record command. The --app option sets the package name of the Android application to profile.
|
|
If the app is not already running, the record command will poll for the app process in a loop with
|
|
an interval of 1ms. So to profile from launch of an application, we can first start the record
|
|
command with --app, then start the app. Below is an example.
|
|
|
|
```sh
|
|
$ python run_simpleperf_on_device.py record
|
|
--app com.example.simpleperf.simpleperfexamplewithnative \
|
|
-g --duration 1 -o /data/local/tmp/perf.data
|
|
# Start the app manually or using the `am` command.
|
|
```
|
|
|
|
To make it convenient to use, app_profiler.py supports using the -a option to start an Activity
|
|
after recording has started.
|
|
|
|
```sh
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .MainActivity
|
|
```
|
|
|
|
## api_profiler.py
|
|
|
|
api_profiler.py is used to control recording in application code. It does preparation work
|
|
before recording, and collects profiling data files after recording.
|
|
|
|
[Here](./android_application_profiling.md#control-recording-in-application-code) are the details.
|
|
|
|
## run_simpleperf_without_usb_connection.py
|
|
|
|
run_simpleperf_without_usb_connection.py records profiling data while the USB cable isn't
|
|
connected. Maybe api_profiler.py is more suitable, which also don't need USB cable when recording.
|
|
Below is an example.
|
|
|
|
```sh
|
|
$ python run_simpleperf_without_usb_connection.py start \
|
|
-p com.example.simpleperf.simpleperfexamplewithnative
|
|
# After the command finishes successfully, unplug the USB cable, run the
|
|
# SimpleperfExampleWithNative app. After a few seconds, plug in the USB cable.
|
|
$ python run_simpleperf_without_usb_connection.py stop
|
|
# It may take a while to stop recording. After that, the profiling data is collected in perf.data
|
|
# on host.
|
|
```
|
|
|
|
## binary_cache_builder.py
|
|
|
|
The binary_cache directory is a directory holding binaries needed by a profiling data file. The
|
|
binaries are expected to be unstripped, having debug information and symbol tables. The
|
|
binary_cache directory is used by report scripts to read symbols of binaries. It is also used by
|
|
report_html.py to generate annotated source code and disassembly.
|
|
|
|
By default, app_profiler.py builds the binary_cache directory after recording. But we can also
|
|
build binary_cache for existing profiling data files using binary_cache_builder.py. It is useful
|
|
when you record profiling data using `simpleperf record` directly, to do system wide profiling or
|
|
record without the USB cable connected.
|
|
|
|
binary_cache_builder.py can either pull binaries from an Android device, or find binaries in
|
|
directories on the host (via -lib).
|
|
|
|
```sh
|
|
# Generate binary_cache for perf.data, by pulling binaries from the device.
|
|
$ python binary_cache_builder.py
|
|
|
|
# Generate binary_cache, by pulling binaries from the device and finding binaries in
|
|
# SimpleperfExampleWithNative.
|
|
$ python binary_cache_builder.py -lib path_of_SimpleperfExampleWithNative
|
|
```
|
|
|
|
## run_simpleperf_on_device.py
|
|
|
|
This script pushes the simpleperf executable on the device, and run a simpleperf command on the
|
|
device. It is more convenient than running adb commands manually.
|
|
|
|
## report.py
|
|
|
|
report.py is a wrapper of the report command on the host. It accepts all options of the report
|
|
command.
|
|
|
|
```sh
|
|
# Report call graph
|
|
$ python report.py -g
|
|
|
|
# Report call graph in a GUI window implemented by Python Tk.
|
|
$ python report.py -g --gui
|
|
```
|
|
|
|
## report_html.py
|
|
|
|
report_html.py generates report.html based on the profiling data. Then the report.html can show
|
|
the profiling result without depending on other files. So it can be shown in local browsers or
|
|
passed to other machines. Depending on which command-line options are used, the content of the
|
|
report.html can include: chart statistics, sample table, flamegraphs, annotated source code for
|
|
each function, annotated disassembly for each function.
|
|
|
|
```sh
|
|
# Generate chart statistics, sample table and flamegraphs, based on perf.data.
|
|
$ python report_html.py
|
|
|
|
# Add source code.
|
|
$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative
|
|
|
|
# Add disassembly.
|
|
$ python report_html.py --add_disassembly
|
|
|
|
# Adding disassembly for all binaries can cost a lot of time. So we can choose to only add
|
|
# disassembly for selected binaries.
|
|
$ python report_html.py --add_disassembly --binary_filter libgame.so
|
|
|
|
# report_html.py accepts more than one recording data file.
|
|
$ python report_html.py -i perf1.data perf2.data
|
|
```
|
|
|
|
Below is an example of generating html profiling results for SimpleperfExampleWithNative.
|
|
|
|
```sh
|
|
$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
|
|
$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative \
|
|
--add_disassembly
|
|
```
|
|
|
|
After opening the generated [report.html](./report_html.html) in a browser, there are several tabs:
|
|
|
|
The first tab is "Chart Statistics". You can click the pie chart to show the time consumed by each
|
|
process, thread, library and function.
|
|
|
|
The second tab is "Sample Table". It shows the time taken by each function. By clicking one row in
|
|
the table, we can jump to a new tab called "Function".
|
|
|
|
The third tab is "Flamegraph". It shows the graphs generated by [inferno](./inferno.md).
|
|
|
|
The fourth tab is "Function". It only appears when users click a row in the "Sample Table" tab.
|
|
It shows information of a function, including:
|
|
|
|
1. A flamegraph showing functions called by that function.
|
|
2. A flamegraph showing functions calling that function.
|
|
3. Annotated source code of that function. It only appears when there are source code files for
|
|
that function.
|
|
4. Annotated disassembly of that function. It only appears when there are binaries containing that
|
|
function.
|
|
|
|
## inferno
|
|
|
|
[inferno](./inferno.md) is a tool used to generate flamegraph in a html file.
|
|
|
|
```sh
|
|
# Generate flamegraph based on perf.data.
|
|
# On Windows, use inferno.bat instead of ./inferno.sh.
|
|
$ ./inferno.sh -sc --record_file perf.data
|
|
|
|
# Record a native program and generate flamegraph.
|
|
$ ./inferno.sh -np surfaceflinger
|
|
```
|
|
|
|
## purgatorio
|
|
|
|
[purgatorio](../scripts/purgatorio/README.md) is a visualization tool to show samples in time order.
|
|
|
|
## pprof_proto_generator.py
|
|
|
|
It converts a profiling data file into pprof.proto, a format used by [pprof](https://github.com/google/pprof).
|
|
|
|
```sh
|
|
# Convert perf.data in the current directory to pprof.proto format.
|
|
$ python pprof_proto_generator.py
|
|
# Show report in pdf format.
|
|
$ pprof -pdf pprof.profile
|
|
|
|
# Show report in html format. To show disassembly, add --tools option like:
|
|
# --tools=objdump:<ndk_path>/toolchains/llvm/prebuilt/linux-x86_64/aarch64-linux-android/bin
|
|
# To show annotated source or disassembly, select `top` in the view menu, click a function and
|
|
# select `source` or `disassemble` in the view menu.
|
|
$ pprof -http=:8080 pprof.profile
|
|
```
|
|
|
|
## report_sample.py
|
|
|
|
It converts a profiling data file into a format used by [FlameGraph](https://github.com/brendangregg/FlameGraph).
|
|
|
|
```sh
|
|
# Convert perf.data in the current directory to a format used by FlameGraph.
|
|
$ python report_sample.py --symfs binary_cache >out.perf
|
|
$ git clone https://github.com/brendangregg/FlameGraph.git
|
|
$ FlameGraph/stackcollapse-perf.pl out.perf >out.folded
|
|
$ FlameGraph/flamegraph.pl out.folded >a.svg
|
|
```
|
|
|
|
## simpleperf_report_lib.py
|
|
|
|
simpleperf_report_lib.py is a Python library used to parse profiling data files generated by the
|
|
record command. Internally, it uses libsimpleperf_report.so to do the work. Generally, for each
|
|
profiling data file, we create an instance of ReportLib, pass it the file path (via SetRecordFile).
|
|
Then we can read all samples through GetNextSample(). For each sample, we can read its event info
|
|
(via GetEventOfCurrentSample), symbol info (via GetSymbolOfCurrentSample) and call chain info
|
|
(via GetCallChainOfCurrentSample). We can also get some global information, like record options
|
|
(via GetRecordCmd), the arch of the device (via GetArch) and meta strings (via MetaInfo).
|
|
|
|
Examples of using simpleperf_report_lib.py are in report_sample.py, report_html.py,
|
|
pprof_proto_generator.py and inferno/inferno.py.
|