您的位置:首页 > 移动开发 > Android开发

Android adb bugreport工具分析和使用

2016-07-19 11:53 696 查看

Android adb bugreport工具分析和使用

标签:
androidbugreport

2016-07-19 11:53
1477人阅读 评论(0)
收藏
举报


分类:
Android升华之路之系统篇(6)


版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

bugreport是什么,怎么用?

Android系统想要成为一个功能完备,生态繁荣的操作系统,那就必须提供完整的应用开发环境。而在应用开发中,app程序的调试分析是日常生产中进程会进行的工作。Android为了方便开发人员分析整个系统平台和某个app在运行一段时间之内的所有信息,专门开发了bugreport工具。这个工具使用起来十分简单,只要在终端执行(linux或者win):

<code class="hljs avrasm has-numbering">adb bugreport > bugreport<span class="hljs-preprocessor">.txt</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

即可生成bugreport文件。但是有一个问题是,这个生成的文件有的时候异常庞大,能够达到15M+,想一想对于一个txt文本格式的文件内容长度达到了15M+是一个什么概念,如果使用文本工具打开查看将是一个噩梦。因此google针对android 5.0(api 21)以上的系统开发了一个叫做battery historian的分析工具,这个工具就是用来解析这个txt文本文件,然后使用web图形的形式展现出来,这样出来的效果更加人性化,更加可读。它的基本界面像下面这个样子:



目前google已经将bettery historian开源了,开源项目的地址:
https://github.com/google/battery-historian

google写了一个比较详细的说明文档,大家可以自行查阅一下。这个工具可以查看以下信息:

<code class="hljs applescript has-numbering">Brightness
CPU <span class="hljs-property">running</span>
Charging <span class="hljs-function_start"><span class="hljs-keyword">on</span></span>
Charging status
Health
JobScheduler
Kernel only uptime
Level
Package active
Partial wakelock
Phone scanning
Phone state
Plug
Plugged
Screen
Temperature
Top app
Voltage
Wifi <span class="hljs-function_start"><span class="hljs-keyword">on</span></span>
Wifi <span class="hljs-property">running</span>
Wifi supplicant</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul>

数据还是比较详细的。

当然,同样的bugreport数据也可以有不同的解析和阅读方式,你如果不太喜欢google的battery historian的话,你还有别的选择,那就是选择Sony开源的ChkBugReport,这个工具提供了不同于battery historian的视角去解读bugreport文件,界面简单明了:



这个项目的文档:
http://developer.sonymobile.com/2012/01/25/new-bugreport-analysis-tool-released-as-open-source/

开源地址首页:
https://github.com/sonyxperiadev/ChkBugReport

这里说明一下,笔者使用过ChkBugReport这个工具,感觉很不错,最好结合google的battery historian;另外ChkBugReport这个工具还有一点bug,不过不影响使用。

bugreport的原理是什么?

下面我们简要分析一下adb bugreport运行的原理。我们知道,使用bugreport只要执行adb bugreport命令就可以了,因此我们的分析肯定是从adbd这个daemon进程开始,我们查看这个进程的代码的时候发现这里处理了bugreport选项:

adb_commandline@system/core/adb/commandline.cpp



我们可以清楚地看到,这里判断如果附带的参数是bugreport的话,那就直接调用send_shell_command函数处理,这个函数的代码比较简单,我们就不分析了,这个函数的功能就是使用shell执行参数中的命令,因此我们这里相当于执行了bugreport命令。

在android设备中,bugreport命令存在于system/bin/目录下,这是一个可执行文件,所以我们要查看这个可执行文件实现的地方,它的实现代码在/frameworks/native/cmds/bugreport/目录下:



我们看到,bugreport的实现是比较简单的,只有一个Android.mk和一个cpp实现代码,我们先看一下Android.mk文件:



这里我们看到该目录下的代码会被编译成一个名字叫做bugreport的可执行文件,这就是我们想要找的。现在我们看一下bugreport.cpp文件的实现,这个文件中代码比较简单,只有一个main函数:

<code class="hljs cpp has-numbering"><span class="hljs-comment">// This program will trigger the dumpstate service to start a call to</span>
<span class="hljs-comment">// dumpstate, then connect to the dumpstate local client to read the</span>
<span class="hljs-comment">// output. All of the dumpstate output is written to stdout, including</span>
<span class="hljs-comment">// any errors encountered while reading/writing the output.</span>
<span class="hljs-keyword">int</span> main() {
<span class="hljs-comment">// Start the dumpstate service.</span>
property_set(<span class="hljs-string">"ctl.start"</span>, <span class="hljs-string">"dumpstate"</span>);

<span class="hljs-comment">// Socket will not be available until service starts.</span>
<span class="hljs-keyword">int</span> s;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">20</span>; i++) {
s = socket_local_client(<span class="hljs-string">"dumpstate"</span>, ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
<span class="hljs-keyword">if</span> (s >= <span class="hljs-number">0</span>)
<span class="hljs-keyword">break</span>;
<span class="hljs-comment">// Try again in 1 second.</span>
sleep(<span class="hljs-number">1</span>);
}

<span class="hljs-keyword">if</span> (s == -<span class="hljs-number">1</span>) {
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Failed to connect to dumpstate service: %s\n"</span>, strerror(errno));
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
}

<span class="hljs-comment">// Set a timeout so that if nothing is read in 3 minutes, we'll stop</span>
<span class="hljs-comment">// reading and quit. No timeout in dumpstate is longer than 60 seconds,</span>
<span class="hljs-comment">// so this gives lots of leeway in case of unforeseen time outs.</span>
<span class="hljs-keyword">struct</span> timeval tv;
tv.tv_sec = <span class="hljs-number">3</span> * <span class="hljs-number">60</span>;
tv.tv_usec = <span class="hljs-number">0</span>;
<span class="hljs-keyword">if</span> (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, <span class="hljs-keyword">sizeof</span>(tv)) == -<span class="hljs-number">1</span>) {
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"WARNING: Cannot set socket timeout: %s\n"</span>, strerror(errno));
}

<span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
<span class="hljs-keyword">char</span> buffer[<span class="hljs-number">65536</span>];
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, <span class="hljs-keyword">sizeof</span>(buffer)));
<span class="hljs-keyword">if</span> (bytes_read == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">break</span>;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (bytes_read == -<span class="hljs-number">1</span>) {
<span class="hljs-comment">// EAGAIN really means time out, so change the errno.</span>
<span class="hljs-keyword">if</span> (errno == EAGAIN) {
errno = ETIMEDOUT;
}
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"\nBugreport read terminated abnormally (%s).\n"</span>, strerror(errno));
<span class="hljs-keyword">break</span>;
}

ssize_t bytes_to_send = bytes_read;
ssize_t bytes_written;
<span class="hljs-keyword">do</span> {
bytes_written = TEMP_FAILURE_RETRY(write(STDOUT_FILENO,
buffer + bytes_read - bytes_to_send,
bytes_to_send));
<span class="hljs-keyword">if</span> (bytes_written == -<span class="hljs-number">1</span>) {
<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Failed to write data to stdout: read %zd, trying to send %zd (%s)\n"</span>,
bytes_read, bytes_to_send, strerror(errno));
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
}
bytes_to_send -= bytes_written;
} <span class="hljs-keyword">while</span> (bytes_written != <span class="hljs-number">0</span> && bytes_to_send > <span class="hljs-number">0</span>);
}

close(s);
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li></ul>

这里的代码非常简单,主要的逻辑就是:

1.启动dumpstate service

2. 和dumpstate service建立socket链接

3. 从socket中读取数据,并且答应到stdout中

4. 读取完成之后关闭socket,然后退出

因此,我们分析的重点需要转移到dumpstate中了。这里说明一下,前面启动dumpstate service的方法是使用系统属性来实现,这个属性的改变消息会被init进程收到,然后init进程会启动dumpstate这个服务。

dumpstate其实也是一个可执行文件,也存在于system/bin目录下。现在我们明白了,其实bugreport就是dumpstate,只是bugreport将dumpstate包装了一下而已。

现在我们需要分析一下dumpstate的实现,它的实现代码在:frameworks/native/cmds/dumpstate目录下,我们看下这个目录下的代码结构:



这里的代码也是十分简单,只要少数的几个实现文件,其中main函数在dumpstate.c文件中,这个main函数我们这里不详细分析了,总结下它的主要工作:

1. 根据启动参数,初始化相关资源

2. 如果启动参数中带有-s的话(init启动会加上这个参数),就表示使用socket,那么就启动socket,并且在这个socket中等待链接。

3. 如果client端(也就是bugreport进程)链接成功,那就初始化所要用到的内存,并且设置优先级为较高优先级,防止被OOM干掉。

4. 然后使用vibrator震动一下(如果设备有这个硬件的话),提示用户开始截取log了

5. 调用dumpstate函数开始真正的dump工作

6. dump完成之后再次调用vibrator震动3次,提示用户dump完成。

现在我们看下dumpstate函数的实现:

<code class="hljs objectivec has-numbering"><span class="hljs-comment">/* dumps the current system state to stdout */</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> dumpstate() {
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> timeout;
time_t now = time(<span class="hljs-literal">NULL</span>);
<span class="hljs-keyword">char</span> build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
<span class="hljs-keyword">char</span> radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
<span class="hljs-keyword">char</span> network[PROPERTY_VALUE_MAX], date[<span class="hljs-number">80</span>];
<span class="hljs-keyword">char</span> build_type[PROPERTY_VALUE_MAX];

property_get(<span class="hljs-string">"ro.build.display.id"</span>, build, <span class="hljs-string">"(unknown)"</span>);
property_get(<span class="hljs-string">"ro.build.fingerprint"</span>, fingerprint, <span class="hljs-string">"(unknown)"</span>);
property_get(<span class="hljs-string">"ro.build.type"</span>, build_type, <span class="hljs-string">"(unknown)"</span>);
property_get(<span class="hljs-string">"ro.baseband"</span>, radio, <span class="hljs-string">"(unknown)"</span>);
property_get(<span class="hljs-string">"ro.bootloader"</span>, bootloader, <span class="hljs-string">"(unknown)"</span>);
property_get(<span class="hljs-string">"gsm.operator.alpha"</span>, network, <span class="hljs-string">"(unknown)"</span>);
strftime(date, <span class="hljs-keyword">sizeof</span>(date), <span class="hljs-string">"%Y-%m-%d %H:%M:%S"</span>, localtime(&now));

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== dumpstate: %s\n"</span>, date);
printf(<span class="hljs-string">"========================================================\n"</span>);

printf(<span class="hljs-string">"\n"</span>);
printf(<span class="hljs-string">"Build: %s\n"</span>, build);
printf(<span class="hljs-string">"Build fingerprint: '%s'\n"</span>, fingerprint); <span class="hljs-comment">/* format is important for other tools */</span>
printf(<span class="hljs-string">"Bootloader: %s\n"</span>, bootloader);
printf(<span class="hljs-string">"Radio: %s\n"</span>, radio);
printf(<span class="hljs-string">"Network: %s\n"</span>, network);

printf(<span class="hljs-string">"Kernel: "</span>);
dump_file(<span class="hljs-literal">NULL</span>, <span class="hljs-string">"/proc/version"</span>);
printf(<span class="hljs-string">"Command line: %s\n"</span>, strtok(cmdline_buf, <span class="hljs-string">"\n"</span>));
printf(<span class="hljs-string">"\n"</span>);

dump_dev_files(<span class="hljs-string">"TRUSTY VERSION"</span>, <span class="hljs-string">"/sys/bus/platform/drivers/trusty"</span>, <span class="hljs-string">"trusty_version"</span>);
run_command(<span class="hljs-string">"UPTIME"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"uptime"</span>, <span class="hljs-literal">NULL</span>);
dump_files(<span class="hljs-string">"UPTIME MMC PERF"</span>, mmcblk0, skip_not_stat, dump_stat_from_fd);
dump_file(<span class="hljs-string">"MEMORY INFO"</span>, <span class="hljs-string">"/proc/meminfo"</span>);
run_command(<span class="hljs-string">"CPU INFO"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"top"</span>, <span class="hljs-string">"-n"</span>, <span class="hljs-string">"1"</span>, <span class="hljs-string">"-d"</span>, <span class="hljs-string">"1"</span>, <span class="hljs-string">"-m"</span>, <span class="hljs-string">"30"</span>, <span class="hljs-string">"-t"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"PROCRANK"</span>, <span class="hljs-number">20</span>, <span class="hljs-string">"procrank"</span>, <span class="hljs-literal">NULL</span>);
dump_file(<span class="hljs-string">"VIRTUAL MEMORY STATS"</span>, <span class="hljs-string">"/proc/vmstat"</span>);
dump_file(<span class="hljs-string">"VMALLOC INFO"</span>, <span class="hljs-string">"/proc/vmallocinfo"</span>);
dump_file(<span class="hljs-string">"SLAB INFO"</span>, <span class="hljs-string">"/proc/slabinfo"</span>);
dump_file(<span class="hljs-string">"ZONEINFO"</span>, <span class="hljs-string">"/proc/zoneinfo"</span>);
dump_file(<span class="hljs-string">"PAGETYPEINFO"</span>, <span class="hljs-string">"/proc/pagetypeinfo"</span>);
dump_file(<span class="hljs-string">"BUDDYINFO"</span>, <span class="hljs-string">"/proc/buddyinfo"</span>);
dump_file(<span class="hljs-string">"FRAGMENTATION INFO"</span>, <span class="hljs-string">"/d/extfrag/unusable_index"</span>);

dump_file(<span class="hljs-string">"KERNEL WAKELOCKS"</span>, <span class="hljs-string">"/proc/wakelocks"</span>);
dump_file(<span class="hljs-string">"KERNEL WAKE SOURCES"</span>, <span class="hljs-string">"/d/wakeup_sources"</span>);
dump_file(<span class="hljs-string">"KERNEL CPUFREQ"</span>, <span class="hljs-string">"/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"</span>);
dump_file(<span class="hljs-string">"KERNEL SYNC"</span>, <span class="hljs-string">"/d/sync"</span>);

run_command(<span class="hljs-string">"PROCESSES"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ps"</span>, <span class="hljs-string">"-P"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"PROCESSES AND THREADS"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ps"</span>, <span class="hljs-string">"-t"</span>, <span class="hljs-string">"-p"</span>, <span class="hljs-string">"-P"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"PROCESSES (SELINUX LABELS)"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ps"</span>, <span class="hljs-string">"-Z"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"LIBRANK"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"librank"</span>, <span class="hljs-literal">NULL</span>);

do_dmesg();

run_command(<span class="hljs-string">"LIST OF OPEN FILES"</span>, <span class="hljs-number">10</span>, SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"lsof"</span>, <span class="hljs-literal">NULL</span>);
for_each_pid(do_showmap, <span class="hljs-string">"SMAPS OF ALL PROCESSES"</span>);
for_each_tid(show_wchan, <span class="hljs-string">"BLOCKED PROCESS WAIT-CHANNELS"</span>);

<span class="hljs-keyword">if</span> (screenshot_path[<span class="hljs-number">0</span>]) {
ALOGI(<span class="hljs-string">"taking screenshot\n"</span>);
run_command(<span class="hljs-literal">NULL</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"/system/bin/screencap"</span>, <span class="hljs-string">"-p"</span>, screenshot_path, <span class="hljs-literal">NULL</span>);
ALOGI(<span class="hljs-string">"wrote screenshot: %s\n"</span>, screenshot_path);
}

<span class="hljs-comment">// dump_file("EVENT LOG TAGS", "/etc/event-log-tags");</span>
<span class="hljs-comment">// calculate timeout</span>
timeout = logcat_timeout(<span class="hljs-string">"main"</span>) + logcat_timeout(<span class="hljs-string">"system"</span>) + logcat_timeout(<span class="hljs-string">"crash"</span>);
<span class="hljs-keyword">if</span> (timeout < <span class="hljs-number">20000</span>) {
timeout = <span class="hljs-number">20000</span>;
}
run_command(<span class="hljs-string">"SYSTEM LOG"</span>, timeout / <span class="hljs-number">1000</span>, <span class="hljs-string">"logcat"</span>, <span class="hljs-string">"-v"</span>, <span class="hljs-string">"threadtime"</span>, <span class="hljs-string">"-d"</span>, <span class="hljs-string">"*:v"</span>, <span class="hljs-literal">NULL</span>);
timeout = logcat_timeout(<span class="hljs-string">"events"</span>);
<span class="hljs-keyword">if</span> (timeout < <span class="hljs-number">20000</span>) {
timeout = <span class="hljs-number">20000</span>;
}
run_command(<span class="hljs-string">"EVENT LOG"</span>, timeout / <span class="hljs-number">1000</span>, <span class="hljs-string">"logcat"</span>, <span class="hljs-string">"-b"</span>, <span class="hljs-string">"events"</span>, <span class="hljs-string">"-v"</span>, <span class="hljs-string">"threadtime"</span>, <span class="hljs-string">"-d"</span>, <span class="hljs-string">"*:v"</span>, <span class="hljs-literal">NULL</span>);
timeout = logcat_timeout(<span class="hljs-string">"radio"</span>);
<span class="hljs-keyword">if</span> (timeout < <span class="hljs-number">20000</span>) {
timeout = <span class="hljs-number">20000</span>;
}
run_command(<span class="hljs-string">"RADIO LOG"</span>, timeout / <span class="hljs-number">1000</span>, <span class="hljs-string">"logcat"</span>, <span class="hljs-string">"-b"</span>, <span class="hljs-string">"radio"</span>, <span class="hljs-string">"-v"</span>, <span class="hljs-string">"threadtime"</span>, <span class="hljs-string">"-d"</span>, <span class="hljs-string">"*:v"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"LOG STATISTICS"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"logcat"</span>, <span class="hljs-string">"-b"</span>, <span class="hljs-string">"all"</span>, <span class="hljs-string">"-S"</span>, <span class="hljs-literal">NULL</span>);

<span class="hljs-comment">/* show the traces we collected in main(), if that was done */</span>
<span class="hljs-keyword">if</span> (dump_traces_path != <span class="hljs-literal">NULL</span>) {
dump_file(<span class="hljs-string">"VM TRACES JUST NOW"</span>, dump_traces_path);
}

<span class="hljs-comment">/* only show ANR traces if they're less than 15 minutes old */</span>
<span class="hljs-keyword">struct</span> stat st;
<span class="hljs-keyword">char</span> anr_traces_path[PATH_MAX];
property_get(<span class="hljs-string">"dalvik.vm.stack-trace-file"</span>, anr_traces_path, <span class="hljs-string">""</span>);
<span class="hljs-keyword">if</span> (!anr_traces_path[<span class="hljs-number">0</span>]) {
printf(<span class="hljs-string">"*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n"</span>);
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">int</span> fd = TEMP_FAILURE_RETRY(open(anr_traces_path,
O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
<span class="hljs-keyword">if</span> (fd < <span class="hljs-number">0</span>) {
printf(<span class="hljs-string">"*** NO ANR VM TRACES FILE (%s): %s\n\n"</span>, anr_traces_path, strerror(errno));
} <span class="hljs-keyword">else</span> {
dump_file_from_fd(<span class="hljs-string">"VM TRACES AT LAST ANR"</span>, anr_traces_path, fd);
}
}

<span class="hljs-comment">/* slow traces for slow operations */</span>
<span class="hljs-keyword">if</span> (anr_traces_path[<span class="hljs-number">0</span>] != <span class="hljs-number">0</span>) {
<span class="hljs-keyword">int</span> tail = strlen(anr_traces_path)-<span class="hljs-number">1</span>;
<span class="hljs-keyword">while</span> (tail > <span class="hljs-number">0</span> && anr_traces_path[tail] != <span class="hljs-string">'/'</span>) {
tail--;
}
<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;
<span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
sprintf(anr_traces_path+tail+<span class="hljs-number">1</span>, <span class="hljs-string">"slow%02d.txt"</span>, i);
<span class="hljs-keyword">if</span> (stat(anr_traces_path, &st)) {
<span class="hljs-comment">// No traces file at this index, done with the files.</span>
<span class="hljs-keyword">break</span>;
}
dump_file(<span class="hljs-string">"VM TRACES WHEN SLOW"</span>, anr_traces_path);
i++;
}
}

<span class="hljs-keyword">int</span> dumped = <span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span> (size_t i = <span class="hljs-number">0</span>; i < NUM_TOMBSTONES; i++) {
<span class="hljs-keyword">if</span> (tombstone_data[i]<span class="hljs-variable">.fd</span> != -<span class="hljs-number">1</span>) {
dumped = <span class="hljs-number">1</span>;
dump_file_from_fd(<span class="hljs-string">"TOMBSTONE"</span>, tombstone_data[i]<span class="hljs-variable">.name</span>, tombstone_data[i]<span class="hljs-variable">.fd</span>);
tombstone_data[i]<span class="hljs-variable">.fd</span> = -<span class="hljs-number">1</span>;
}
}
<span class="hljs-keyword">if</span> (!dumped) {
printf(<span class="hljs-string">"*** NO TOMBSTONES to dump in %s\n\n"</span>, TOMBSTONE_DIR);
}

dump_file(<span class="hljs-string">"NETWORK DEV INFO"</span>, <span class="hljs-string">"/proc/net/dev"</span>);
dump_file(<span class="hljs-string">"QTAGUID NETWORK INTERFACES INFO"</span>, <span class="hljs-string">"/proc/net/xt_qtaguid/iface_stat_all"</span>);
dump_file(<span class="hljs-string">"QTAGUID NETWORK INTERFACES INFO (xt)"</span>, <span class="hljs-string">"/proc/net/xt_qtaguid/iface_stat_fmt"</span>);
dump_file(<span class="hljs-string">"QTAGUID CTRL INFO"</span>, <span class="hljs-string">"/proc/net/xt_qtaguid/ctrl"</span>);
dump_file(<span class="hljs-string">"QTAGUID STATS INFO"</span>, <span class="hljs-string">"/proc/net/xt_qtaguid/stats"</span>);

<span class="hljs-keyword">if</span> (!stat(PSTORE_LAST_KMSG, &st)) {
<span class="hljs-comment">/* Also TODO: Make console-ramoops CAP_SYSLOG protected. */</span>
dump_file(<span class="hljs-string">"LAST KMSG"</span>, PSTORE_LAST_KMSG);
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">/* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */</span>
dump_file(<span class="hljs-string">"LAST KMSG"</span>, <span class="hljs-string">"/proc/last_kmsg"</span>);
}

<span class="hljs-comment">/* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */</span>
run_command(<span class="hljs-string">"LAST LOGCAT"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"logcat"</span>, <span class="hljs-string">"-L"</span>, <span class="hljs-string">"-v"</span>, <span class="hljs-string">"threadtime"</span>,
<span class="hljs-string">"-b"</span>, <span class="hljs-string">"all"</span>, <span class="hljs-string">"-d"</span>, <span class="hljs-string">"*:v"</span>, <span class="hljs-literal">NULL</span>);

<span class="hljs-comment">/* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */</span>

run_command(<span class="hljs-string">"NETWORK INTERFACES"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"link"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"IPv4 ADDRESSES"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"-4"</span>, <span class="hljs-string">"addr"</span>, <span class="hljs-string">"show"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"IPv6 ADDRESSES"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"-6"</span>, <span class="hljs-string">"addr"</span>, <span class="hljs-string">"show"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"IP RULES"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"rule"</span>, <span class="hljs-string">"show"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"IP RULES v6"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"-6"</span>, <span class="hljs-string">"rule"</span>, <span class="hljs-string">"show"</span>, <span class="hljs-literal">NULL</span>);

dump_route_tables();

run_command(<span class="hljs-string">"ARP CACHE"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"-4"</span>, <span class="hljs-string">"neigh"</span>, <span class="hljs-string">"show"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"IPv6 ND CACHE"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"ip"</span>, <span class="hljs-string">"-6"</span>, <span class="hljs-string">"neigh"</span>, <span class="hljs-string">"show"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"IPTABLES"</span>, <span class="hljs-number">10</span>, SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"iptables"</span>, <span class="hljs-string">"-L"</span>, <span class="hljs-string">"-nvx"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"IP6TABLES"</span>, <span class="hljs-number">10</span>, SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"ip6tables"</span>, <span class="hljs-string">"-L"</span>, <span class="hljs-string">"-nvx"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"IPTABLE NAT"</span>, <span class="hljs-number">10</span>, SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"iptables"</span>, <span class="hljs-string">"-t"</span>, <span class="hljs-string">"nat"</span>, <span class="hljs-string">"-L"</span>, <span class="hljs-string">"-nvx"</span>, <span class="hljs-literal">NULL</span>);
<span class="hljs-comment">/* no ip6 nat */</span>
run_command(<span class="hljs-string">"IPTABLE RAW"</span>, <span class="hljs-number">10</span>, SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"iptables"</span>, <span class="hljs-string">"-t"</span>, <span class="hljs-string">"raw"</span>, <span class="hljs-string">"-L"</span>, <span class="hljs-string">"-nvx"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"IP6TABLE RAW"</span>, <span class="hljs-number">10</span>, SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"ip6tables"</span>, <span class="hljs-string">"-t"</span>, <span class="hljs-string">"raw"</span>, <span class="hljs-string">"-L"</span>, <span class="hljs-string">"-nvx"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"WIFI NETWORKS"</span>, <span class="hljs-number">20</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"wpa_cli"</span>, <span class="hljs-string">"IFNAME=wlan0"</span>, <span class="hljs-string">"list_networks"</span>, <span class="hljs-literal">NULL</span>);

<span class="hljs-preprocessor">#ifdef FWDUMP_bcmdhd</span>
run_command(<span class="hljs-string">"ND OFFLOAD TABLE"</span>, <span class="hljs-number">5</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"wlutil"</span>, <span class="hljs-string">"nd_hostip"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"DUMP WIFI INTERNAL COUNTERS (1)"</span>, <span class="hljs-number">20</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"wlutil"</span>, <span class="hljs-string">"counters"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"ND OFFLOAD STATUS (1)"</span>, <span class="hljs-number">5</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"wlutil"</span>, <span class="hljs-string">"nd_status"</span>, <span class="hljs-literal">NULL</span>);

<span class="hljs-preprocessor">#endif</span>
dump_file(<span class="hljs-string">"INTERRUPTS (1)"</span>, <span class="hljs-string">"/proc/interrupts"</span>);

run_command(<span class="hljs-string">"NETWORK DIAGNOSTICS"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"connectivity"</span>, <span class="hljs-string">"--diag"</span>, <span class="hljs-literal">NULL</span>);

<span class="hljs-preprocessor">#ifdef FWDUMP_bcmdhd</span>
run_command(<span class="hljs-string">"DUMP WIFI STATUS"</span>, <span class="hljs-number">20</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"dhdutil"</span>, <span class="hljs-string">"-i"</span>, <span class="hljs-string">"wlan0"</span>, <span class="hljs-string">"dump"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"DUMP WIFI INTERNAL COUNTERS (2)"</span>, <span class="hljs-number">20</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"wlutil"</span>, <span class="hljs-string">"counters"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"ND OFFLOAD STATUS (2)"</span>, <span class="hljs-number">5</span>,
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"wlutil"</span>, <span class="hljs-string">"nd_status"</span>, <span class="hljs-literal">NULL</span>);
<span class="hljs-preprocessor">#endif</span>
dump_file(<span class="hljs-string">"INTERRUPTS (2)"</span>, <span class="hljs-string">"/proc/interrupts"</span>);

print_properties();

run_command(<span class="hljs-string">"VOLD DUMP"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"vdc"</span>, <span class="hljs-string">"dump"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"SECURE CONTAINERS"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"vdc"</span>, <span class="hljs-string">"asec"</span>, <span class="hljs-string">"list"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"FILESYSTEMS & FREE SPACE"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"df"</span>, <span class="hljs-literal">NULL</span>);

run_command(<span class="hljs-string">"LAST RADIO LOG"</span>, <span class="hljs-number">10</span>, <span class="hljs-string">"parse_radio_log"</span>, <span class="hljs-string">"/proc/last_radio_log"</span>, <span class="hljs-literal">NULL</span>);

printf(<span class="hljs-string">"------ BACKLIGHTS ------\n"</span>);
printf(<span class="hljs-string">"LCD brightness="</span>);
dump_file(<span class="hljs-literal">NULL</span>, <span class="hljs-string">"/sys/class/leds/lcd-backlight/brightness"</span>);
printf(<span class="hljs-string">"Button brightness="</span>);
dump_file(<span class="hljs-literal">NULL</span>, <span class="hljs-string">"/sys/class/leds/button-backlight/brightness"</span>);
printf(<span class="hljs-string">"Keyboard brightness="</span>);
dump_file(<span class="hljs-literal">NULL</span>, <span class="hljs-string">"/sys/class/leds/keyboard-backlight/brightness"</span>);
printf(<span class="hljs-string">"ALS mode="</span>);
dump_file(<span class="hljs-literal">NULL</span>, <span class="hljs-string">"/sys/class/leds/lcd-backlight/als"</span>);
printf(<span class="hljs-string">"LCD driver registers:\n"</span>);
dump_file(<span class="hljs-literal">NULL</span>, <span class="hljs-string">"/sys/class/leds/lcd-backlight/registers"</span>);
printf(<span class="hljs-string">"\n"</span>);

<span class="hljs-comment">/* Binder state is expensive to look at as it uses a lot of memory. */</span>
dump_file(<span class="hljs-string">"BINDER FAILED TRANSACTION LOG"</span>, <span class="hljs-string">"/sys/kernel/debug/binder/failed_transaction_log"</span>);
dump_file(<span class="hljs-string">"BINDER TRANSACTION LOG"</span>, <span class="hljs-string">"/sys/kernel/debug/binder/transaction_log"</span>);
dump_file(<span class="hljs-string">"BINDER TRANSACTIONS"</span>, <span class="hljs-string">"/sys/kernel/debug/binder/transactions"</span>);
dump_file(<span class="hljs-string">"BINDER STATS"</span>, <span class="hljs-string">"/sys/kernel/debug/binder/stats"</span>);
dump_file(<span class="hljs-string">"BINDER STATE"</span>, <span class="hljs-string">"/sys/kernel/debug/binder/state"</span>);

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== Board\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);

dumpstate_board();
printf(<span class="hljs-string">"\n"</span>);

<span class="hljs-comment">/* Migrate the ril_dumpstate to a dumpstate_board()? */</span>
<span class="hljs-keyword">char</span> ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {<span class="hljs-number">0</span>};
property_get(<span class="hljs-string">"ril.dumpstate.timeout"</span>, ril_dumpstate_timeout, <span class="hljs-string">"30"</span>);
<span class="hljs-keyword">if</span> (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - <span class="hljs-number">1</span>) > <span class="hljs-number">0</span>) {
<span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> == strncmp(build_type, <span class="hljs-string">"user"</span>, PROPERTY_VALUE_MAX - <span class="hljs-number">1</span>)) {
<span class="hljs-comment">// su does not exist on user builds, so try running without it.</span>
<span class="hljs-comment">// This way any implementations of vril-dump that do not require</span>
<span class="hljs-comment">// root can run on user builds.</span>
run_command(<span class="hljs-string">"DUMP VENDOR RIL LOGS"</span>, atoi(ril_dumpstate_timeout),
<span class="hljs-string">"vril-dump"</span>, <span class="hljs-literal">NULL</span>);
} <span class="hljs-keyword">else</span> {
run_command(<span class="hljs-string">"DUMP VENDOR RIL LOGS"</span>, atoi(ril_dumpstate_timeout),
SU_PATH, <span class="hljs-string">"root"</span>, <span class="hljs-string">"vril-dump"</span>, <span class="hljs-literal">NULL</span>);
}
}

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== Android Framework Services\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);

<span class="hljs-comment">/* the full dumpsys is starting to take a long time, so we need
to increase its timeout.  we really need to do the timeouts in
dumpsys itself... */</span>
run_command(<span class="hljs-string">"DUMPSYS"</span>, <span class="hljs-number">60</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-literal">NULL</span>);

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== Checkins\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);

run_command(<span class="hljs-string">"CHECKIN BATTERYSTATS"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"batterystats"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"CHECKIN MEMINFO"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"meminfo"</span>, <span class="hljs-string">"--checkin"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"CHECKIN NETSTATS"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"netstats"</span>, <span class="hljs-string">"--checkin"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"CHECKIN PROCSTATS"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"procstats"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"CHECKIN USAGESTATS"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"usagestats"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-literal">NULL</span>);
run_command(<span class="hljs-string">"CHECKIN PACKAGE"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"package"</span>, <span class="hljs-string">"--checkin"</span>, <span class="hljs-literal">NULL</span>);

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== Running Application Activities\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);

run_command(<span class="hljs-string">"APP ACTIVITIES"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"activity"</span>, <span class="hljs-string">"all"</span>, <span class="hljs-literal">NULL</span>);

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== Running Application Services\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);

run_command(<span class="hljs-string">"APP SERVICES"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"activity"</span>, <span class="hljs-string">"service"</span>, <span class="hljs-string">"all"</span>, <span class="hljs-literal">NULL</span>);

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== Running Application Providers\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);

run_command(<span class="hljs-string">"APP SERVICES"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"dumpsys"</span>, <span class="hljs-string">"activity"</span>, <span class="hljs-string">"provider"</span>, <span class="hljs-string">"all"</span>, <span class="hljs-literal">NULL</span>);

printf(<span class="hljs-string">"========================================================\n"</span>);
printf(<span class="hljs-string">"== dumpstate: done\n"</span>);
printf(<span class="hljs-string">"========================================================\n"</span>);
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li><li>156</li><li>157</li><li>158</li><li>159</li><li>160</li><li>161</li><li>162</li><li>163</li><li>164</li><li>165</li><li>166</li><li>167</li><li>168</li><li>169</li><li>170</li><li>171</li><li>172</li><li>173</li><li>174</li><li>175</li><li>176</li><li>177</li><li>178</li><li>179</li><li>180</li><li>181</li><li>182</li><li>183</li><li>184</li><li>185</li><li>186</li><li>187</li><li>188</li><li>189</li><li>190</li><li>191</li><li>192</li><li>193</li><li>194</li><li>195</li><li>196</li><li>197</li><li>198</li><li>199</li><li>200</li><li>201</li><li>202</li><li>203</li><li>204</li><li>205</li><li>206</li><li>207</li><li>208</li><li>209</li><li>210</li><li>211</li><li>212</li><li>213</li><li>214</li><li>215</li><li>216</li><li>217</li><li>218</li><li>219</li><li>220</li><li>221</li><li>222</li><li>223</li><li>224</li><li>225</li><li>226</li><li>227</li><li>228</li><li>229</li><li>230</li><li>231</li><li>232</li><li>233</li><li>234</li><li>235</li><li>236</li><li>237</li><li>238</li><li>239</li><li>240</li><li>241</li><li>242</li><li>243</li><li>244</li><li>245</li><li>246</li><li>247</li><li>248</li><li>249</li><li>250</li><li>251</li><li>252</li><li>253</li><li>254</li><li>255</li><li>256</li><li>257</li><li>258</li><li>259</li><li>260</li><li>261</li><li>262</li><li>263</li><li>264</li><li>265</li><li>266</li><li>267</li><li>268</li><li>269</li><li>270</li><li>271</li><li>272</li><li>273</li><li>274</li><li>275</li><li>276</li><li>277</li><li>278</li><li>279</li><li>280</li><li>281</li><li>282</li><li>283</li><li>284</li><li>285</li><li>286</li><li>287</li><li>288</li><li>289</li><li>290</li><li>291</li><li>292</li><li>293</li><li>294</li><li>295</li><li>296</li><li>297</li><li>298</li><li>299</li><li>300</li><li>301</li><li>302</li><li>303</li><li>304</li><li>305</li></ul>

上面的代码比较长,是因为所要dump的模块太多,但是基本逻辑还是比较清楚的,我们看到基本的数据来源就是:

1.系统属性

2./proc和/sys节点文件

3.执行shell命令获得相关输出

4.logcat输出

5.Android Framework Services信息基本使用dumpsys命令通过binder调用服务中的dump函数获得信息

这里我们需要看一下dumpsys命令的实现,这个命令也是比较简单,实现全部在main函数中:

<code class="hljs objectivec has-numbering"><span class="hljs-keyword">int</span> main(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span>* <span class="hljs-keyword">const</span> argv[])
{
signal(SIGPIPE, SIG_IGN);
sp<IServiceManager> sm = defaultServiceManager();
fflush(stdout);
<span class="hljs-keyword">if</span> (sm == <span class="hljs-literal">NULL</span>) {
ALOGE(<span class="hljs-string">"Unable to get default service manager!"</span>);
aerr << <span class="hljs-string">"dumpsys: Unable to get default service manager!"</span> << endl;
<span class="hljs-keyword">return</span> <span class="hljs-number">20</span>;
}

Vector<String16> services;
Vector<String16> args;
<span class="hljs-keyword">bool</span> showListOnly = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">if</span> ((argc == <span class="hljs-number">2</span>) && (strcmp(argv[<span class="hljs-number">1</span>], <span class="hljs-string">"-l"</span>) == <span class="hljs-number">0</span>)) {
showListOnly = <span class="hljs-literal">true</span>;
}
<span class="hljs-keyword">if</span> ((argc == <span class="hljs-number">1</span>) || showListOnly) {
services = sm->listServices();
services<span class="hljs-variable">.sort</span>(sort_func);
args<span class="hljs-variable">.add</span>(String16(<span class="hljs-string">"-a"</span>));
} <span class="hljs-keyword">else</span> {
services<span class="hljs-variable">.add</span>(String16(argv[<span class="hljs-number">1</span>]));
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i=<span class="hljs-number">2</span>; i<argc; i++) {
args<span class="hljs-variable">.add</span>(String16(argv[i]));
}
}

<span class="hljs-keyword">const</span> size_t N = services<span class="hljs-variable">.size</span>();

<span class="hljs-keyword">if</span> (N > <span class="hljs-number">1</span>) {
<span class="hljs-comment">// first print a list of the current services</span>
aout << <span class="hljs-string">"Currently running services:"</span> << endl;

<span class="hljs-keyword">for</span> (size_t i=<span class="hljs-number">0</span>; i<N; i++) {
sp<IBinder> service = sm->checkService(services[i]);
<span class="hljs-keyword">if</span> (service != <span class="hljs-literal">NULL</span>) {
aout << <span class="hljs-string">"  "</span> << services[i] << endl;
}
}
}

<span class="hljs-keyword">if</span> (showListOnly) {
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}

<span class="hljs-keyword">for</span> (size_t i=<span class="hljs-number">0</span>; i<N; i++) {
sp<IBinder> service = sm->checkService(services[i]);
<span class="hljs-keyword">if</span> (service != <span class="hljs-literal">NULL</span>) {
<span class="hljs-keyword">if</span> (N > <span class="hljs-number">1</span>) {
aout << <span class="hljs-string">"------------------------------------------------------------"</span>
<span class="hljs-string">"-------------------"</span> << endl;
aout << <span class="hljs-string">"DUMP OF SERVICE "</span> << services[i] << <span class="hljs-string">":"</span> << endl;
}
<span class="hljs-keyword">int</span> err = service->dump(STDOUT_FILENO, args);
<span class="hljs-keyword">if</span> (err != <span class="hljs-number">0</span>) {
aerr << <span class="hljs-string">"Error dumping service info: ("</span> << strerror(err)
<< <span class="hljs-string">") "</span> << services[i] << endl;
}
} <span class="hljs-keyword">else</span> {
aerr << <span class="hljs-string">"Can't find service: "</span> << services[i] << endl;
}
}

<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li></ul>

我们看到它的代码逻辑就是,通过Binder的SM查找参数中的service,然后通过:

<code class="hljs perl has-numbering"><span class="hljs-keyword">int</span> err = service-><span class="hljs-keyword">dump</span>(STDOUT_FILENO, args);</code><ul style="" class="pre-numbering"><li>1</li></ul>

这句来调用service的dump函数。

dumpstate会调用到所有binder中的service的dump函数,因为dumpstate函数执行了这一句:

<code class="hljs applescript has-numbering">/* <span class="hljs-keyword">the</span> full dumpsys <span class="hljs-keyword">is</span> starting <span class="hljs-keyword">to</span> take a long <span class="hljs-property">time</span>, so we need
<span class="hljs-keyword">to</span> increase <span class="hljs-keyword">its</span> <span class="hljs-keyword">timeout</span>.  we really need <span class="hljs-keyword">to</span> do <span class="hljs-keyword">the</span> timeouts <span class="hljs-keyword">in</span>
dumpsys itself... */
run_command(<span class="hljs-string">"DUMPSYS"</span>, <span class="hljs-number">60</span>, <span class="hljs-string">"dumpsys"</span>, NULL);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>

直接执行dumpsys,没有参数,并且注释中也说的很清楚,就是采集所有的信息。这会执行以下service的dump函数(执行dumpsys | grep “DUMP OF SERVICE”可以看到):

<code class="hljs vhdl has-numbering">DUMP <span class="hljs-keyword">OF</span> SERVICE DockObserver:
DUMP <span class="hljs-keyword">OF</span> SERVICE SurfaceFlinger:
DUMP <span class="hljs-keyword">OF</span> SERVICE accessibility:
DUMP <span class="hljs-keyword">OF</span> SERVICE account:
DUMP <span class="hljs-keyword">OF</span> SERVICE activity:
DUMP <span class="hljs-keyword">OF</span> SERVICE alarm:
DUMP <span class="hljs-keyword">OF</span> SERVICE android.security.keystore:
DUMP <span class="hljs-keyword">OF</span> SERVICE android.service.gatekeeper.IGateKeeperService:
DUMP <span class="hljs-keyword">OF</span> SERVICE appops:
DUMP <span class="hljs-keyword">OF</span> SERVICE appwidget:
DUMP <span class="hljs-keyword">OF</span> SERVICE assetatlas:
DUMP <span class="hljs-keyword">OF</span> SERVICE audio:
DUMP <span class="hljs-keyword">OF</span> SERVICE backup:
DUMP <span class="hljs-keyword">OF</span> SERVICE battery:
DUMP <span class="hljs-keyword">OF</span> SERVICE batteryproperties:
DUMP <span class="hljs-keyword">OF</span> SERVICE batterystats:
DUMP <span class="hljs-keyword">OF</span> SERVICE bluetooth_manager:
DUMP <span class="hljs-keyword">OF</span> SERVICE carrier_config:
DUMP <span class="hljs-keyword">OF</span> SERVICE clipboard:
DUMP <span class="hljs-keyword">OF</span> SERVICE commontime_management:
DUMP <span class="hljs-keyword">OF</span> SERVICE connectivity:
DUMP <span class="hljs-keyword">OF</span> SERVICE consumer_ir:
DUMP <span class="hljs-keyword">OF</span> SERVICE content:
DUMP <span class="hljs-keyword">OF</span> SERVICE country_detector:
DUMP <span class="hljs-keyword">OF</span> SERVICE cpuinfo:
DUMP <span class="hljs-keyword">OF</span> SERVICE dbinfo:
DUMP <span class="hljs-keyword">OF</span> SERVICE device_policy:
DUMP <span class="hljs-keyword">OF</span> SERVICE deviceidle:
DUMP <span class="hljs-keyword">OF</span> SERVICE devicestoragemonitor:
DUMP <span class="hljs-keyword">OF</span> SERVICE diskstats:
DUMP <span class="hljs-keyword">OF</span> SERVICE display:
DUMP <span class="hljs-keyword">OF</span> SERVICE display.qservice:
DUMP <span class="hljs-keyword">OF</span> SERVICE dreams:
DUMP <span class="hljs-keyword">OF</span> SERVICE drm.drmManager:
DUMP <span class="hljs-keyword">OF</span> SERVICE dropbox:
DUMP <span class="hljs-keyword">OF</span> SERVICE ethernet:
DUMP <span class="hljs-keyword">OF</span> SERVICE fingerprint:
DUMP <span class="hljs-keyword">OF</span> SERVICE gfxinfo:
DUMP <span class="hljs-keyword">OF</span> SERVICE graphicsstats:
DUMP <span class="hljs-keyword">OF</span> SERVICE imms:
DUMP <span class="hljs-keyword">OF</span> SERVICE input:
DUMP <span class="hljs-keyword">OF</span> SERVICE input_method:
DUMP <span class="hljs-keyword">OF</span> SERVICE iphonesubinfo:
DUMP <span class="hljs-keyword">OF</span> SERVICE isms:
DUMP <span class="hljs-keyword">OF</span> SERVICE isub:
DUMP <span class="hljs-keyword">OF</span> SERVICE jobscheduler:
DUMP <span class="hljs-keyword">OF</span> SERVICE launcherapps:
DUMP <span class="hljs-keyword">OF</span> SERVICE location:
DUMP <span class="hljs-keyword">OF</span> SERVICE lock_settings:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.audio_flinger:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.audio_policy:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.camera:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.camera.proxy:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.player:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.radio:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.resource_manager:
DUMP <span class="hljs-keyword">OF</span> SERVICE media.sound_trigger_hw:
DUMP <span class="hljs-keyword">OF</span> SERVICE media_projection:
DUMP <span class="hljs-keyword">OF</span> SERVICE media_router:
DUMP <span class="hljs-keyword">OF</span> SERVICE media_session:
DUMP <span class="hljs-keyword">OF</span> SERVICE meminfo:
DUMP <span class="hljs-keyword">OF</span> SERVICE midi:
DUMP <span class="hljs-keyword">OF</span> SERVICE mount:
DUMP <span class="hljs-keyword">OF</span> SERVICE netpolicy:
DUMP <span class="hljs-keyword">OF</span> SERVICE netstats:
DUMP <span class="hljs-keyword">OF</span> SERVICE network_management:
DUMP <span class="hljs-keyword">OF</span> SERVICE network_score:
DUMP <span class="hljs-keyword">OF</span> SERVICE nfc:
DUMP <span class="hljs-keyword">OF</span> SERVICE notification:
DUMP <span class="hljs-keyword">OF</span> SERVICE <span class="hljs-keyword">package</span>:
DUMP <span class="hljs-keyword">OF</span> SERVICE permission:
DUMP <span class="hljs-keyword">OF</span> SERVICE persistent_data_block:
DUMP <span class="hljs-keyword">OF</span> SERVICE phone:
DUMP <span class="hljs-keyword">OF</span> SERVICE power:
DUMP <span class="hljs-keyword">OF</span> SERVICE print:
DUMP <span class="hljs-keyword">OF</span> SERVICE processinfo:
DUMP <span class="hljs-keyword">OF</span> SERVICE procstats:
DUMP <span class="hljs-keyword">OF</span> SERVICE restrictions:
DUMP <span class="hljs-keyword">OF</span> SERVICE rttmanager:
DUMP <span class="hljs-keyword">OF</span> SERVICE samplingprofiler:
DUMP <span class="hljs-keyword">OF</span> SERVICE scheduling_policy:
DUMP <span class="hljs-keyword">OF</span> SERVICE search:
DUMP <span class="hljs-keyword">OF</span> SERVICE sensorservice:
DUMP <span class="hljs-keyword">OF</span> SERVICE serial:
DUMP <span class="hljs-keyword">OF</span> SERVICE servicediscovery:
DUMP <span class="hljs-keyword">OF</span> SERVICE simphonebook:
DUMP <span class="hljs-keyword">OF</span> SERVICE sip:
DUMP <span class="hljs-keyword">OF</span> SERVICE statusbar:
DUMP <span class="hljs-keyword">OF</span> SERVICE telecom:
DUMP <span class="hljs-keyword">OF</span> SERVICE telephony.registry:
DUMP <span class="hljs-keyword">OF</span> SERVICE textservices:
DUMP <span class="hljs-keyword">OF</span> SERVICE trust:
DUMP <span class="hljs-keyword">OF</span> SERVICE uimode:
DUMP <span class="hljs-keyword">OF</span> SERVICE updatelock:
DUMP <span class="hljs-keyword">OF</span> SERVICE usagestats:
DUMP <span class="hljs-keyword">OF</span> SERVICE usb:
DUMP <span class="hljs-keyword">OF</span> SERVICE user:
DUMP <span class="hljs-keyword">OF</span> SERVICE vibrator:
DUMP <span class="hljs-keyword">OF</span> SERVICE voiceinteraction:
DUMP <span class="hljs-keyword">OF</span> SERVICE wallpaper:
DUMP <span class="hljs-keyword">OF</span> SERVICE webviewupdate:
DUMP <span class="hljs-keyword">OF</span> SERVICE wifi:
DUMP <span class="hljs-keyword">OF</span> SERVICE wifip2p:
DUMP <span class="hljs-keyword">OF</span> SERVICE wifiscanner:
DUMP <span class="hljs-keyword">OF</span> SERVICE window:</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li></ul>

这里总结以下,上面的bugreport整体逻辑如下图描述(如果图片太小看不清,请下载图片并查看):



adb bugreport的其他选项

bugreport本身并没有什么选项,主要是通过dumpsys等命令配合完成,详见battery historian项目主页:https://github.com/google/battery-historian,以下是个总结:

1). 重置电池统计信息:

<code class="hljs livecodeserver has-numbering">adb <span class="hljs-built_in">shell</span> dumpsys batterystats <span class="hljs-comment">--reset</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

2). Wakelock analysis全部wakelock信息:

<code class="hljs lasso has-numbering">adb shell dumpsys batterystats <span class="hljs-subst">--</span>enable <span class="hljs-literal">full</span><span class="hljs-attribute">-wake</span><span class="hljs-attribute">-history</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

3). Kernel trace analysis分析内核,主要分析wakeup source和wakelock activities,首先使能kernel分析:

<code class="hljs sql has-numbering">$ adb root
$ adb shell

# <span class="hljs-operator"><span class="hljs-keyword">Set</span> the events <span class="hljs-keyword">to</span> trace.
$ echo <span class="hljs-string">"power:wakeup_source_activate"</span> >> /d/tracing/set_event
$ echo <span class="hljs-string">"power:wakeup_source_deactivate"</span> >> /d/tracing/set_event

# The <span class="hljs-keyword">default</span> trace <span class="hljs-keyword">size</span> <span class="hljs-keyword">for</span> most devices <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>MB, which <span class="hljs-keyword">is</span> relatively low <span class="hljs-keyword">and</span> might cause the logs <span class="hljs-keyword">to</span> overflow.
# <span class="hljs-number">8</span>MB <span class="hljs-keyword">to</span> <span class="hljs-number">10</span>MB should be a decent <span class="hljs-keyword">size</span> <span class="hljs-keyword">for</span> <span class="hljs-number">5</span>-<span class="hljs-number">6</span> hours <span class="hljs-keyword">of</span> logging.

$ echo <span class="hljs-number">8192</span> > /d/tracing/buffer_size_kb

$ echo <span class="hljs-number">1</span> > /d/tracing/tracing_on</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul>

然后获得log:

<code class="hljs smalltalk has-numbering"><span class="hljs-char">$ </span>echo <span class="hljs-number">0</span> > /d/tracing/tracing_on
<span class="hljs-char">$ </span>adb pull /d/tracing/trace <some path>

# <span class="hljs-class">Take</span> a bug report at this time.
<span class="hljs-char">$ </span>adb bugreport > bugreport.txt</code>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: