Compile Android#
Use the envsetup.sh script to initialize the environment: source build/envsetup.sh or . build/envsetup.sh
To view the complete list of available commands, run the following command: hmm
![img](AOSP Debugging Guide.assets/hmm.png)
Framework Debugging#
top#
VIRT
: This memory usage represents the address space occupied by an application; it counts all memory requested by the application regardless of whether it is actually used. It is normal to allocate more memory when writing programs to avoid errors and not worry about usage.RES
: Resident memory usage. This value represents the actual memory used by the application, but there are two small issues: some things may be swapped out (SWAP), and some memory may be shared.SHR
: Shared memory. This means that this block of memory may also be used by other applications.DATA
: Memory occupied by data. This is the actual data space requested by the program, which is genuinely used during execution.
vmstat#
vmstat is a command that displays system information. For example, it shows the available capacity of main memory and the operational status of the CPU. When the vmstat command is executed as is, it displays information about current processes, memory, swap, devices, interrupts, and CPU. Additionally, if the “-d” or “-p” option is added, it will display read/write status on partitions and disks, etc. When specifying the “-f” option, it will show the number of processes created from system startup to command execution.
meminfo#
cat /proc/meminfo
free#
-b Display capacity in bytes (default)
-k Display capacity in kilobytes
-m Display capacity in MB
-h Display capacity units, including G, M
-t Also shows the total of physical memory and swap memory
strace#
Commonly used to trace system calls and signals received during process execution.
time#
Measures the time taken from calling the specified command to its completion, including user CPU time and system CPU time. The measurement results will be output to standard error after the output of the specified command. The actual CPU time used by the command code is the user CPU time. Therefore, if a non-existent command is passed as a parameter to the time command, the user CPU time becomes 0. Sleep time is not included.
size#
Displays the size of various segments of an object file or linked library file.
file#
Determines and displays the file type.
addr2line#
Resolves so files.
Skip Boot Initialization#
adb shell settings put global device_provisioned 1
readelf#
View information about ELF format files.
logcat#
adb root; adb remount
Clear cache: adb logcat -c
If unable to clear, specify the area to clear: adb logcat -c main/system/event/kernel/all (log buffer)
View cache: adb logcat -g
Set maximum logcat cache: adb logcat -G 100M
dump meminfo#
adb shell dumpsys meminfo
or for a specific package
adb shell dumpsys meminfo packageName
printk#
- Print debug log
printk("%d", intA);
- Print the size of memory occupied by a variable
printk("sizeof(*intA)=%d", sizeof(*intA));
View CPU Architecture#
adb shell getprop ro.product.cpu.abi
Service#
Service list: adb shell service list
Check if a service exists: adb shell service check SurfaceFlinger
Activity#
adb shell dumpsys activity top | grep ACTIVITY
adb shell am start -n ActivityName
Get Parameters#
getprop View all information parameters of the machine
getprop ro.serialno View the serial number of the machine
getprop ro.carrier View the CID number of the machine
getprop ro.hardware View the machine board code
getprop ro.bootloader View the SPL (Hboot) version number
getprop ro.build.version.release View the system version (8, 9...)
getprop ro.build.display.id Get the vendor system version
CPU Frequency#
Root privileges (directly enter su command)
cd sys/devices/system/cpu/cpu0/cpufreq
ls files as follows
cpuinfo_cur_freq: Current CPU running frequency
cpuinfo_max_freq: This file specifies the highest operating frequency the processor can run (unit: kilohertz)
cpuinfo_min_freq: This file specifies the lowest operating frequency the processor can run (unit: kilohertz)
Screen#
View:
adb shell
wm size Get the current resolution of the phone
wm density Get the current screen density of the phone (e.g., 560dpi)
Modify:
wm size 1096*2560
wm density 420
Restore:
wm size reset
wm density reset
View Virtual Address#
adb root; adb remount
adb shell
ps -A | grep camera View the process ID of the service (e.g., 4712)
cd proc/4712 Enter the folder of the process ID
more maps View virtual memory addresses
SELinux Mode#
adb shell setenforce 0 (temporarily effective, disables SELinux mode)
adb shell setenforce 1 (enables, activates SELinux mode)
Get Path#
adb shell dumpsys SurfaceFlinger Check the bottom for running APK
adb shell pm path "com.**" Get the path
Property System#
Android controls many things through the set and get methods of SystemProperties. Generally, an upper layer adds a control switch using this method, and there are many prop files in the system. They are system/build.prop, system/etc/prop.default, vendor/build.prop, vendor/default.prop. Below is a description of the composition of these files.
- system/build.prop
This is mainly composed of device(platform)sample\product/system.prop, and additional properties added in the build directory.
- system/etc/prop.default
Mainly the PRODUCT_SYSTEM_DEFAULT_PROPERTIES added by the system.
- vendor/build.prop (more important)
Mainly the PRODUCT_PROPERTY_OVERRIDES added by the system. Adding this property in device.mk will compile it here, but in the 9.0 system, adding it here will be ineffective, and the value cannot be obtained.
- vendor/default.prop (will be overridden by the same property in the build.prop in the same directory)
Mainly the PRODUCT_DEFAULT_PROPERTY_OVERRIDES added by the system.
Prefixes:
- ro: Read-only properties that cannot be modified.
- persist: After modifying the property, it remains effective after reboot. Data will be saved to the /data/property directory. Properties with other prefixes are only stored in memory after being set and are not saved to disk, so they revert to default values after reboot.
- ctrl: Used to start and stop services. Each service must be defined in init.rc. Once init receives a request to set the ctrl.start property, the property service will use this property value as the service name to find and start the service. The result of starting this service will be placed in the init.svc. property.
Android Signature#
The system signatures in the Android source code are uniformly stored at: build/target/product/security
-
.pem type files: When Android signs an APK, a .pem file is an X.509 digital certificate containing the user's public key and other information, used for decryption. The file format can store not only digital certificates but also various keys, which can be public and are mainly used to verify whether an App or others are signed by the corresponding private key.
-
.pk8 type files: Files with the .pk8 extension correspond to PKCS 8 and are used to store private keys, which must be kept confidential and not made public.
There are a total of 5 types of keys under the Android system signature path:
- testkey: The platform default key. If no special changes are made, the system compilation uses this key by default. Since testkey is public, anyone can obtain it, so there is a certain risk. If the project has special requirements, it is generally recommended to use a self-created key as the system default key.
- platform: One of the core application signatures of the platform, the signed APK completes the core functions of the system. The UID of the processes where these APKs reside is system. The manifest node has added sharedUserId="android.uid.system".
- shared: The signed APK can share data with home/contacts processes. The manifest node has added android="android.uid.shared". Generally used in APKs related to tel.
- media: The signed APK is part of media/download. The manifest node has added android="android.media". Generally applied to some APKs related to media. Each APK package will set the LOCAL_CERTIFICATE property in its corresponding Android.mk, specifying one of the keys. (If this variable is not set, testkey is used by default.)
- verity: A special system signature. The system undergoes compilation processing during compilation. It needs to be generated separately.
Generate Signature#
Execute the command in the Android root directory to generate releasekey, platform, shared, media. Taking platform as an example, other keys are generated in the same way.
development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
Explanation:
- Country abbreviation: C, can only be the country letter abbreviation, e.g., China: CN
- State/Province abbreviation: S
- City abbreviation: L
- Organization Name: O
- Organizational Unit Name (e.g., section): OU
- Common Name: CN. The name of the unit applying for the code signing certificate or the website domain name.
The system will prompt you to enter the password required to generate the key; just press enter. If a key password is set, the compilation will not pass.
The generated key is located in the Android root directory. Move the key to /build/target/product/security
and replace the previous key, while also using OpenSSL tools to verify whether the generated key is normal. Taking releaseKey as an example, execute the following command: openssl x509 -noout -subject -issuer -in releaseKey.x509.pem
Generate verity_key
- Compile verity: Compile verity in the Android root directory.
make generate_verity_key (mmm system/extras/verity/)
- Generate veritykey signature:
development/tools/make_key veritykey '/C=CN/ST=ChengDu/L=ChengDu/O=123/OU=13/CN=123/emailAddress=test@123.com'
- Execute the following command to generate .pk8 .pem files:
out/host/linux-x86/bin/generate_verity_key -convert veritykey.x509.pem verity_key
Usage and Configuration of Signatures
The usage of signatures is divided into two situations:
- No distinction between user and debug versions, only replace the key used for the current device compilation.
- Distinguish between user and debug versions, using different keys when compiling different versions.
No distinction between user and debug versions
- Copy the various .pk8 and .pem files generated in the Android root directory to the
build/target/product/security/
directory, overwriting all previous default keys. Rename veritykey.pk8, veritykey.x509.pem, verity_key to verity.pk8, verity.x509.pem, verity_key. - Modify Android configuration:
- The variable defined in
/build/core/config.mk
:DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
PS: PRODUCT_DEFAULT_DEV_CERTIFICATE
: The LOCAL_CERTIFICATE
variable defined in the mk file. If the mk file defines LOCAL_CERTIFICATE
, the compilation will use the defined signature file. If the LOCAL_CERTIFICATE
variable is not defined, it enters the else process.
- The variable defined in
/build/core/Makefile
:ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/releasekey) BUILD_VERSION_TAGS += release-keys
PS: This piece of code mainly checks the DEFAULT_SYSTEM_DEV_CERTIFICATE
variable defined in config.mk and uses the corresponding build_key during compilation. After flashing, you can check via getprop build.tags
.
- Modify SELinux:
system/sepolicy/private/keys.conf system/sepolicy/prebuilts/api/{apilevel}/private/keys.conf
Distinguish user and debug versions
Taking testkey as an example:
- Create a folder named security under the
device/project/
path to store the newly created key files. This folder is only for key files. Subsequent steps will conditionally check the path. - In
device/project/product.mk
, perform conditional checks: Get TARGET_BUILD_VARIANT. IfTARGET_BUILD_VARIANT
is userdebug/eng, usebuild/make/target/product/security/testkey
; otherwise, use the key in our custom folder.
Determine System Signature Key of Android Device#
adb root; adb remount
adb shell
cd system
getprop | grep ro.build.tags
# You can see a line ro.build.tags=release-keys
Generate Signature Files for Third-party Apps#
In third-party App applications, because they do not go through Android system compilation, if there is no signature file, special permissions cannot be used for installation. Therefore, a corresponding .keystore file can be provided for their use.
In the path where your generated key is located:
- Generate platform.pem file: platform.pk8 generates a
.pem
file:openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt
- Generate platform.p12 file:
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:pwd -name name
, where name is the alias name, pwd is the alias password. - Generate platform.keystore:
keytool -importkeystore -deststorepass pwd -destkeystore ./platform.keystore -srckeystore ./platform.p12 -srcstoretype PKCS12 -srcstorepass pwd
The above three steps can generate a platform.keystore
file in that path. This file can be used for APK signing.
Bootchart Performance Tool Usage#
The Android system source code has an implementation of bootchart, located in system/core/init/bootchart.cpp
. Bootchart is implemented by being embedded in the init process and measures in the background. However, the measurement period of bootchart is after the init process starts and does not include the startup time of uboot and kernel.
Steps to Use Bootchart on Android Platform#
- Enable the bootchart program for the debugging device to perform necessary boot logs:
adb shell 'touch /data/bootchart/enabled'
- After
adb reboot
the debugging device, connect the debugging device to the Ubuntu computer, and execute the command in the Android root directory:android$ ./system/core/init/grab-bootchart.sh
- The bootchart icon will be generated in the Android root directory.
Command to Switch Between Landscape and Portrait#
# Switch to landscape:
su
settings put system user_rotation 3
settings put system accelerometer_rotation 0
# Switch to portrait:
settings put system accelerometer_rotation 1/2/3 (change as needed)
Kernel Log Command#
adb shell cat proc/kmsg
Modify SELinux and Make Compilation#
make selinux_policy
: This command can compile all SELinux files, completing a make in about 50 seconds.make filename
: For example:
make plat_file_contexts -j9;
make plat_sepolicy.cil -j9;
make vendor_sepolicy.cil -j9;
make vendor_property_contexts -j9;
Synchronize SELinux Modifications to Device#
adb push out/target/product/product/vendor/etc/selinux/* vendor/etc/selinux/*
adb push out/target/product/product/system/etc/selinux/* system/etc/selinux/*
Parse Crash Address#
symbols/vendor$ addr2line -f -e bin/test_service 000000000000ac40
_ZN12UpdateSocket9handleMsgEPv
vendor/..../test.cpp:87
Clear Application Data and View Version#
Clear application data: adb shell pm clear com.test.upgrade
View application version number: dumpsys package com.test.upgrade | grep version
Compile Without Generating odex Files#
LOCAL_DEX_PREOPT := false
ANR Log Extraction#
The xxx_app_anr file generally records less process stack information than the traces file.
Therefore, if there are traces, we will analyze and locate the bug based on that file.
- The traces file is located in the
/data/anr/
directory. By default, a traces.txt file will be generated every time an ANR occurs, but the later occurrences will overwrite the previous ones. - The xxx_app_anr file is located in the
/data/system/dropbox/
directory, stored in different compressed packages. Generated by Dropbox.
When an ANR occurs, you can use the adb pull
command to extract the above two directories from the device.
Disable/Restore Kernel Log Printing via Serial Port#
By adjusting the printk printing level:
- Disable printing: dmesg -n1
- Restore printing: dmesg -n8
- Restore disable: echo 0 > /proc/sys/kernel/printk
- Restore printing: echo 7 > /proc/sys/kernel/printk
Open Touch Coordinate Display#
- Open:
settings put system pointer_location 1
- Close:
settings put system pointer_location 0
Open a Specific Application#
- View application package name:
dumpsys package
- Open a specific package to view activity:
dumpsys package com.***.***
- View package location:
adb shell pm path com.***.***
- Open application:
am start ***/***.activity
- View the activity of the currently opened application:
dumpsys activity top | grep ACTIVITY
Get the Current Open Application Package Name#
adb shell dumpsys window | grep mCurrentFocus
Selinux#
Classification:
- untrusted_app: Third-party app, no Android platform signature, no system permissions.
- platform_app: Has Android platform signature, no system permissions.
- system_app: Has Android platform signature and system permissions.
- priv_app: An app without a platform signature (definitely no system permissions), but in Android.mk
LOCAL_PRIVILEGED_MODULE := true
, check the app in the priv-app directory.