From 8672571f5b9ced839fb3f5e24dd7fc93ac5de6c8 Mon Sep 17 00:00:00 2001 From: "rick.chan" Date: Mon, 28 Dec 2020 16:09:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=20=E5=B8=B8=E8=A7=81?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: rick.chan --- .../BootChart/Android_8_上使用_BootChart.md | 70 ++++++++++++++++++- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/Software/Applications/BootChart/Android_8_上使用_BootChart.md b/Software/Applications/BootChart/Android_8_上使用_BootChart.md index 12b5d36..1b3c0c6 100644 --- a/Software/Applications/BootChart/Android_8_上使用_BootChart.md +++ b/Software/Applications/BootChart/Android_8_上使用_BootChart.md @@ -1,6 +1,6 @@ # Android 8 上使用 BootChart -## 基本原理 +## 1.基本原理 bootchart 可以在 Android 系统启动到 init 阶段时开始收集系统信息,并保存成 Log 文件。可在开发机上使用 bootchart 命令对这些 Log 文件进行分析,生成图表。 @@ -45,7 +45,7 @@ on property:sys.boot_completed=1 bootchart stop ``` -## 使用方法 +## 2.使用方法 在开发机上先安装 bootchart 和 pybootchartgui 用于处理和分析开机数据: @@ -136,7 +136,7 @@ echo "Clean up ${TMPDIR}/ and ./${TARBALL%.tgz}.png when done" ``` -## 性能对比 +## 3.性能对比 Google 还给我们提供了一个比较脚本,用来比较两次开机的数据: @@ -163,3 +163,67 @@ ${AndroidSrc}/compare-bootcharts.py cmp1_dir cmp2_dir ``` 也可以将以上命令按自己的实际需求写成脚本文件来使用。 + +## 4.常见错误处理 + +### 4.1.ZeroDivisionError / substring not found + +执行脚本时,如提示如下错误: + +```bash +File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line +201, in draw_chart +yscale = float(chart_bounds[3]) / max(y for (x,y) in data) +ZeroDivisionError: float division +# 或 +state = get_proc_state( sample.state ) +File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 105, in get_proc_state +return "RSDTZXW".index(flag) + 1 +ValueError: substring not found +``` + +需修改 /usr/share/pyshared/pybootchartgui/ 或 /usr/lib/python2.7/dist-packages/pybootchartgui 目录的 draw.py, parsing.py, samples.py 三个文件。 + +```diff +# draw.py +@ 190 @ def draw_chart(ctx, color, fill, chart_bounds, data, proc_tree): + def transform_point_coords(point, x_base, y_base, xscale, yscale, x_trans, y_trans): + x = (point[0] - x_base) * xscale + x_trans + y = (point[1] - y_base) * -yscale + y_trans + bar_h + return x, y + +- xscale = float(chart_bounds[2]) / max(x for (x,y) in data) +- yscale = float(chart_bounds[3]) / max(y for (x,y) in data) ++ xscale = float(chart_bounds[2]) / max(0.00001, max(x for (x,y) in data)) ++ yscale = float(chart_bounds[3]) / max(0.00001, max(y for (x,y) in data)) + +first = transform_point_coords(data[0], x_shift, 0, xscale, yscale, chart_bounds[0], chart_bounds[1]) +last = transform_point_coords(data[-1], x_shift, 0, xscale, yscale, chart_bounds[0], chart_bounds[1]) + +@ 104 @ def get_proc_state(flag): +- return "RSDTZXW".index(flag) + 1 ++ return "RSDTZXW".find(flag) + 1 + +def draw_text(ctx, text, color, x, y): +``` + +```diff +# parsing.py +@ 142 @ def _parse_proc_disk_stat_log(file, numCpu): + for sample1, sample2 in zip(disk_stat_samples[:-1], disk_stat_samples[1:]): + interval = sample1.time - sample2.time + sums = [ a - b for a, b in zip(sample1.diskdata, sample2.diskdata) ] ++ if interval == 0: ++ interval = 1 + readTput = sums[0] / 2.0 * 100.0 / interval + writeTput = sums[1] / 2.0 * 100.0 / interval +``` + +```diff +# samples.py +@ 81 @ def calc_load(self, userCpu, sysCpu, interval): ++ if interval == 0: ++ interval = 1 + userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval + sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval +```