• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# FaultLoggerd组件
2
3-   简介
4-   架构
5-   目录
6-   使用说明
7    -   DumpCatcher
8    -   ProcessDump
9-   处理流程
10    -   DumpCatcher SDK接口处理流程
11    -   ProcessDump命令行处理流程
12    -   进程崩溃处理流程
13-   相关仓
14
15## 简介
16
17Faultloggerd部件是OpenHarmony中C/C++运行时崩溃临时日志的生成及管理模块。系统开发者可以在预设的路径下找到崩溃日志,定位相关问题。
18
19## 架构
20
21![架构](figures/faultloggerd架构图.png)
22
23* SignalHandler:信号处理器,接收系统异常信号,触发抓取进程异常时的现场信息。
24* DumpCatcher:堆栈信息抓取工具库,提供了抓取指定进程和线程的堆栈栈信息的能力。
25* FaultloggerdClient:崩溃临时日志管理客户端,接收申请文件描述符、堆栈导出等请求。
26* ProcessDump:进程信息抓取二进制工具,通过命令行方式提供抓取指定进程、线程堆栈信息的能力。
27* crasher:崩溃构造器,提供了崩溃构造和模拟能力。
28* FaultloggerdServer:核心服务处理模块,接收并处理客户端的请求。
29* FaultloggerdSecure:权限校验模块,对运行时崩溃日志生成和抓取提供权限管理和校验能力。
30* FaultloggerdConfig:崩溃临时日志管理模块。
31
32目前主要支持对以下异常信号的处理:
33
34| 信号值 | 信号      | 解释            | 触发原因                                                     |
35| ------ | --------- | --------------- | ------------------------------------------------------------ |
36| 4      | SIGILL    | 非法指令        | 执行了非法指令,通常是因为可执行文件本身出现错误,或者试图执行数据段,堆栈溢出时也有可能产生这个信号。 |
37| 5      | SIGTRAP   | 断点或陷阱异常  | 由断点指令或其它trap指令产生。                               |
38| 6      | SIGABRT   | abort发出的信号 | 调用abort函数生成的信号。                                    |
39| 7      | SIGBUS    | 非法内存访问    | 非法地址,包括内存地址对齐(alignment)出错。比如访问一个四个字长的整数,但其地址不是4的倍数。它与SIGSEGV的区别在于后者是由于对合法存储地址的非法访问触发的(如访问不属于自己存储空间或只读存储空间)。 |
40| 8      | SIGFPE    | 浮点异常        | 在发生致命的算术运算错误时发出,不仅包括浮点运算错误,还包括溢出及除数为0等其它所有的算术的错误。 |
41| 11     | SIGSEGV   | 无效内存访问    | 试图访问未分配给自己的内存,或试图往没有写权限的内存地址写数据。 |
42| 16     | SIGSTKFLT | 栈溢出          | 堆栈溢出。                                                   |
43| 31     | SIGSYS    | 系统调用异常    | 非法的系统调用。                                             |
44
45## 目录
46
47```txt
48faultloggerd/
49├── OAT.xml
50├── common                                 # 公共定义
51├── faultloggerd.gni
52├── interfaces                             # 接口存放目录
53│   └── innerkits
54│       ├── dump_catcher                   # 抓取调用栈基础库
55│       ├── faultloggerd_client            # 崩溃临时日志管理服务客户端接口
56│       └── signal_handler                 # 异常信号处理器
57├── ohos.build
58├── services                               # 崩溃临时日志管理服务
59│   ├── BUILD.gn
60│   ├── config                             # 启动配置
61│   ├── fault_logger_config.cpp            # 日志文件管理
62│   ├── fault_logger_config.h              # 日志文件管理
63│   ├── fault_logger_daemon.cpp            # Faultloggerd 服务提供
64│   ├── fault_logger_daemon.h              # Faultloggerd 服务提供
65│   ├── fault_logger_secure.cpp            # 权限管理与校验
66│   ├── fault_logger_secure.h              # 权限管理与校验
67│   ├── main.cpp
68│   └── test
69├── test                                   # 测试目录
70│   ├── BUILD.gn
71│   ├── fuzztest                           # 模糊测试
72│   ├── performancetest                    # 性能测试
73│   └── systemtest                         # 系统功能测试
74└── tools                                  # 工具
75    ├── crasher_c                          # 崩溃构造工具(C)
76    ├── crasher_cpp                        # 崩溃构造工具(C++)
77    └── process_dump                       # 进程信息抓取工具
78```
79
80## 使用说明
81
82### DumpCatcher
83
84DumpCatcher是指提供给第三方应用使用的抓取调用栈基础库,其中包含了打印指定进程(或线程)的栈信息的接口函数。
85
86接口类名:`DfxDumpCatcher`
87
88接口方法名:`bool DumpCatch(const int pid, const int tid, std::string& msg);`
89
90接口参数说明:
91
92* 接口返回值:
93  * `true`:回栈成功,回栈信息存储在`msg`字符串对象中;
94  * `false`:回栈失败。
95* 输入参数:
96  * `pid`:希望回栈的进程号,如果需要回栈进程中的所有线程,则`tid`设定为`0`;
97  * `tid`:希望回栈的线程号;
98* 输出参数:
99  * `msg`:如果回栈成功,则通过`msg`输出回栈后的信息。
100
101> 注意:此接口需要调用者是管理员(system,root)用户,或者只抓取自己用户拥有的进程信息。抓取非本用户组进程调用栈时还需具备读取对方`/proc/pid/maps`及ptrace到对方进程的权限。
102
103样例代码:
104
105* dump_catcher_demo.h
106
107```c++
108#ifndef DUMP_CATCHER_DEMO_H
109#define DUMP_CATCHER_DEMO_H
110
111#include <inttypes.h>
112
113#define NOINLINE __attribute__((noinline))
114
115#define GEN_TEST_FUNCTION(FuncNumA, FuncNumB)          \
116    __attribute__((noinline)) int TestFunc##FuncNumA() \
117    {                                                  \
118        return TestFunc##FuncNumB();                   \
119    }
120
121// test functions for callstack depth test
122int TestFunc0(void);
123int TestFunc1(void);
124int TestFunc2(void);
125int TestFunc3(void);
126int TestFunc4(void);
127int TestFunc5(void);
128int TestFunc6(void);
129int TestFunc7(void);
130int TestFunc8(void);
131int TestFunc9(void);
132int TestFunc10(void);
133
134#endif // DUMP_CATCHER_DEMO_H
135```
136
137  * dump_catcher_demo.cpp
138
139```c++
140#include "dump_catcher_dump.h"
141
142#include <iostream>
143#include <string>
144#include <unistd.h>
145#include "dfx_dump_catcher.h"
146using namespace std;
147
148NOINLINE int TestFunc10(void)
149{
150    OHOS::HiviewDFX::DfxDumpCatcher dumplog;
151    string msg = "";
152    bool ret = dumplog.DumpCatch(getpid(), gettid(), msg);
153    if (ret) {
154        cout << msg << endl;
155    }
156    return 0;
157}
158
159// auto gen function
160GEN_TEST_FUNCTION(0, 1)
161GEN_TEST_FUNCTION(1, 2)
162GEN_TEST_FUNCTION(2, 3)
163GEN_TEST_FUNCTION(3, 4)
164GEN_TEST_FUNCTION(4, 5)
165GEN_TEST_FUNCTION(5, 6)
166GEN_TEST_FUNCTION(6, 7)
167GEN_TEST_FUNCTION(7, 8)
168GEN_TEST_FUNCTION(8, 9)
169GEN_TEST_FUNCTION(9, 10)
170
171int main(int argc, char *argv[])
172{
173    TestFunc0();
174    return 0;
175}
176```
177
178* BUILD.gn179
180```gn
181import("//base/hiviewdfx/faultloggerd/faultloggerd.gni")
182import("//build/ohos.gni")
183
184config("dumpcatcherdemo_config") {
185  visibility = [ ":*" ]
186
187  include_dirs = [
188    ".",
189    "//utils/native/base/include",
190    "//base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher/include/",
191  ]
192}
193
194ohos_executable("dumpcatcherdemo") {
195  sources = [ "dump_catcher_demo.cpp" ]
196
197  configs = [ ":dumpcatcherdemo_config" ]
198
199  deps = [
200    "//base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher:lib_dfx_dump_catcher",
201    "//utils/native/base:utils",
202  ]
203
204  external_deps = [ "hilog_native:libhilog" ]
205
206  install_enable = true
207  part_name = "faultloggerd"
208  subsystem_name = "hiviewdfx"
209}
210```
211
212* 执行结果:
213
214```txt
215# ./dumpcatcherdemo
216#00 pc 0000000000000981(00000000004a8981) /data/test/dumpcatcherdemo
217#01 pc 0000000000000a6d(00000000004a8a6d) /data/test/dumpcatcherdemo
218#02 pc 0000000000000a63(00000000004a8a63) /data/test/dumpcatcherdemo
219#03 pc 0000000000000a59(00000000004a8a59) /data/test/dumpcatcherdemo
220#04 pc 0000000000000a4f(00000000004a8a4f) /data/test/dumpcatcherdemo
221#05 pc 0000000000000a45(00000000004a8a45) /data/test/dumpcatcherdemo
222#06 pc 0000000000000a3b(00000000004a8a3b) /data/test/dumpcatcherdemo
223#07 pc 0000000000000a31(00000000004a8a31) /data/test/dumpcatcherdemo
224#08 pc 0000000000000a27(00000000004a8a27) /data/test/dumpcatcherdemo
225#09 pc 0000000000000a1d(00000000004a8a1d) /data/test/dumpcatcherdemo
226#10 pc 0000000000000a13(00000000004a8a13) /data/test/dumpcatcherdemo
227#11 pc 0000000000000a77(00000000004a8a77) /data/test/dumpcatcherdemo
228#12 pc 00000000000c2b08(00000000b6fafb08) /system/lib/ld-musl-arm.so.1(__libc_start_main+116)
229#13 pc 0000000000000938(00000000004a8938) /data/test/dumpcatcherdemo
230#14 pc 00000000000008c4(00000000004a88c4) /data/test/dumpcatcherdemo
231```
232
233### ProcessDump
234
235ProcessDump是指提供给用户的一个抓取调用栈命令行工具,该工具通过`-p`、`-t`参数指定进程和线程,命令执行后在命令行窗口打印指定的进程的线程栈信息。
236
237工具名称:`processdump`
238
239位置:`/system/bin`
240
241参数说明:
242
243* `-p [pid]`:打印指定进程下面的所有线程栈信息;
244* `-p [pid] -t [tid]`:打印指定进程下面的指定线程信息。
245
246返回打印说明:如果栈信息解析成功,则将信息显示到标准输出。
247
248> 注意:使用此接口需要调用者是管理员(system,root)用户。
249
250范例:查询hiview主线程当前调用栈
251
252```txt
253# ps -A | grep hiview
254  114 ?        00:00:00 hiview
255# processdump -p 114 -t 114
256Tid:114, Name:hiview
257#00 pc 0000000000089824(00000000b6f44824) /system/lib/ld-musl-arm.so.1(ioctl+68)
258#01 pc 000000000002a709(00000000b6c56709) /system/lib/libipc_core.z.so(_ZN4OHOS15BinderConnector11WriteBinderEmPv+16)
259#02 pc 000000000002ba75(00000000b6c57a75) /system/lib/libipc_core.z.so(_ZN4OHOS13BinderInvoker18TransactWithDriverEb+224)
260#03 pc 000000000002bb37(00000000b6c57b37) /system/lib/libipc_core.z.so(_ZN4OHOS13BinderInvoker13StartWorkLoopEv+22)
261#04 pc 000000000002c211(00000000b6c58211) /system/lib/libipc_core.z.so(_ZN4OHOS13BinderInvoker10JoinThreadEb+36)
262#05 pc 0000000000038d07(00000000004bcd07) /system/bin/hiview(_ZNSt3__h6vectorINS_9sub_matchINS_11__wrap_iterIPKcEEEENS_9allocatorIS6_EEE8__appendEj+596)
263#06 pc 0000000000028655(00000000004ac655) /system/bin/hiview
264#07 pc 00000000000c2b08(00000000b6f7db08) /system/lib/ld-musl-arm.so.1(__libc_start_main+116)
265#08 pc 00000000000285f4(00000000004ac5f4) /system/bin/hiview
266#09 pc 0000000000028580(00000000004ac580) /system/bin/hiview
267```
268
269## 处理流程
270
271### DumpCatcher SDK接口处理流程
272
273![DumpCatcher调用流程图](figures/dumpcatcher调用流程.png)
274
2751. 进程A调用`DumpCatcher`库提供的`DumpCatch()`接口,申请dump指定进程和线程的堆栈信息;
2762. `DumpCatcher`接收到进程A的dump请求后,运行`ProcessDump`程序开始准备dump堆栈信息;
2773. 在dump堆栈信息之前先通过`Faultloggerd`校验用户权限;
2784. 返回权限校验结果,满足权限则返回文件描述符,将回栈结果返回给`DumpCatcher`。
279
280### ProcessDump命令行处理流程
281
282![ProcessDump调用流程图](figures/processdump调用流程.png)
283
2841. Shell通过命令行指令`processdump -p [pid] -t [tid]`申请dump指定进程和线程的堆栈信息;
2852. 在dump堆栈信息之前先通过`Faultloggerd`校验用户权限;
2863. 返回权限校验结果,满足权限则返回文件描述符,将回栈结果写入标准输出。
287
288### 进程崩溃处理流程
289
290![进程崩溃faultloggerd处理流程](figures/crash调用流程.png)
291
2921. 进程B通过安装信号处理器,通过`DFX_SignalHandler`函数检测进程崩溃异常信号;
2932. `SignalHandler`检测到异常信号后Fork出子进程,并运行`ProcessDump`程序开始dump崩溃进程和线程的堆栈信息;
2943. `ProcessDump`程序在读取异常堆栈信息后将日志写入到`Faultloggerd`中的临时存储目录;
2954. `Faultloggerd`根据需要将故障通过`hiview`提供的`AddFaultLog()`接口上报给`hiview`进行后续处理。
296
297
298## 相关仓
299
300[DFX子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/DFX%E5%AD%90%E7%B3%BB%E7%BB%9F.md)
301
302[hiviewdfx\_hiview](https://gitee.com/openharmony/hiviewdfx_hiview/blob/master/README_zh.md)
303
304[hiviewdfx\_hilog](https://gitee.com/openharmony/hiviewdfx_hilog/blob/master/README_zh.md)
305
306[hiviewdfx\_hiappevent](https://gitee.com/openharmony/hiviewdfx_hiappevent/blob/master/README_zh.md)
307
308[hiviewdfx\_hisysevent](https://gitee.com/openharmony/hiviewdfx_hisysevent/blob/master/README_zh.md)
309
310**hiviewdfx\_faultloggerd**
311
312[hiviewdfx\_hilog\_lite](https://gitee.com/openharmony/hiviewdfx_hilog_lite/blob/master/README_zh.md)
313
314[hiviewdfx\_hievent\_lite](https://gitee.com/openharmony/hiviewdfx_hievent_lite/blob/master/README_zh.md)
315
316[hiviewdfx\_hiview\_lite](https://gitee.com/openharmony/hiviewdfx_hiview_lite/blob/master/README_zh.md)
317
318