Andorid系统启动流程分析工具BootChart在7.1上的使用
程序员文章站
2022-05-23 17:35:54
...
准备工作
bootchart相关代码在system/core/init/bootchart.cpp,看一下Android.mk是否已经将文件编译进去了
include $(CLEAR_VARS)
LOCAL_CPPFLAGS := $(init_cflags)
LOCAL_SRC_FILES:= \
bootchart.cpp \
builtins.cpp \
devices.cpp \
init.cpp \
keychords.cpp \
property_service.cpp \
signal_handler.cpp \
ueventd.cpp \
ueventd_parser.cpp \
watchdogd.cpp \
LOCAL_MODULE:= init
LOCAL_C_INCLUDES += \
system/extras/ext4_utils \
system/core/mkbootimg
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
可以看到bootchart.cpp已经编进去了所以没问题,直接去抓log
首先抓设备的log
如果/data下面没有bootchart文件夹,那么先创建文件夹
cd /data
mkdir bootchart
然后执行抓取log的时长设定
echo 40 > /data/bootchart/start
然后重启设备,设备会再下一次开机的时候抓取log到/data/bootchart/文件夹下,40这个值是抓取分析的时间,以实际情况为准,不过40秒一般设备都已经启动完毕了
- 重启后在/data/bootchart/下面有相应文件生成
可进入shell后执行指令打包
/data/bootchart # tar -czf bootchart.tgz
接下来就是去Linux主机处理数据并画图了
首先安装工具
sudo apt-get install bootchart
sudo apt-get install pybootchartgui
然后随便找个目录将刚才设备内的 bootchart.tgz拷贝到Linux主机,执行pybootchartgui bootchart.tgz 就会在该目录下生成png文件
parsing '/home/jimmy/bootchart/bootchart.tgz'
parsing 'header'
parsing 'kernel_pacct'
parsing 'proc_diskstats.log'
parsing 'proc_ps.log'
warning: no parent for pid '2' with ppid '0'
parsing 'proc_stat.log'
parsing 'start'
merged 0 logger processes
pruned 153 process, 0 exploders, 4 threads, and 0 runs
False
bootchart written to 'bootchart.png'
打开png文件看看
根据提示的颜色可以分析CPU、IO占用情况,同时我觉得这个工具对于系统启动的时序学习挺有用的,可以看到在某一特定时间点,各个进程并行执行的状况。
Bug
有个小细节Android 7.1 的BootChart.cpp好像有bug,该bug会导致设置抓取后不断重启,修改方式如下:
--- a/init/bootchart.cpp
+++ b/init/bootchart.cpp
@@ -129,7 +129,7 @@ static void do_log_procs(FILE* log) {
snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
std::string cmdline;
android::base::ReadFileToString(filename, &cmdline);
- const char* full_name = cmdline.c_str(); // So we stop at the first NUL.
+ //const char* full_name = cmdline.c_str(); // So we stop at the first NUL.
// Read process stat line.
snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
@@ -140,7 +140,7 @@ static void do_log_procs(FILE* log) {
size_t open = stat.find('(');
size_t close = stat.find_last_of(')');
if (open != std::string::npos && close != std::string::npos) {
- stat.replace(open + 1, close - open - 1, full_name);
+ //stat.replace(open + 1, close - open - 1, full_name);
}
}
fputs(stat.c_str(), log);