簡介
Faultloggerd部件是OpenHarmony中C/C++運行時崩潰臨時日志的生成及管理模塊。面向基于 Rust 開發(fā)的部件,F(xiàn)aultloggerd 提供了Rust Panic故障日志生成能力。系統(tǒng)開發(fā)者可以在預(yù)設(shè)的路徑下找到故障日志,定位相關(guān)問題。
架構(gòu)
- Native InnerKits 接口
- Rust 接口
- PanicHandler:Rust PANIC故障處理器,封裝faultloggerd回棧能力支持rust模塊PANIC故障回棧。
- Rustc Demangle:Rust 符號demangle庫,支持Rust模塊mangled符號解析。
- Faultlogger Daemon 服務(wù)
- FaultloggerdServer:核心服務(wù)處理模塊,接收并處理客戶端的請求。
- FaultloggerdSecure:權(quán)限校驗?zāi)K,對運行時崩潰日志生成和抓取提供權(quán)限管理和校驗?zāi)芰Α?/li>
- FaultloggerdConfig:崩潰臨時日志管理模塊。
- FaultloggerdPipe:數(shù)據(jù)管道傳輸管理模塊,提供數(shù)據(jù)傳輸管道申請和管理能力。
- 工具
目前主要支持對以下C/C++運行時崩潰異常信號的處理:
信號值 | 信號 | 解釋 | 觸發(fā)原因 |
---|---|---|---|
4 | SIGILL | 非法指令 | 執(zhí)行了非法指令,通常是因為可執(zhí)行文件本身出現(xiàn)錯誤,或者試圖執(zhí)行數(shù)據(jù)段,堆棧溢出時也有可能產(chǎn)生這個信號。 |
5 | SIGTRAP | 斷點或陷阱異常 | 由斷點指令或其它trap指令產(chǎn)生。 |
6 | SIGABRT | abort發(fā)出的信號 | 調(diào)用abort函數(shù)生成的信號。 |
7 | SIGBUS | 非法內(nèi)存訪問 | 非法地址,包括內(nèi)存地址對齊(alignment)出錯。比如訪問一個四個字長的整數(shù),但其地址不是4的倍數(shù)。它與SIGSEGV的區(qū)別在于后者是由于對合法存儲地址的非法訪問觸發(fā)的(如訪問不屬于自己存儲空間或只讀存儲空間)。 |
8 | SIGFPE | 浮點異常 | 在發(fā)生致命的算術(shù)運算錯誤時發(fā)出,不僅包括浮點運算錯誤,還包括溢出及除數(shù)為0等其它所有的算術(shù)的錯誤。 |
11 | SIGSEGV | 無效內(nèi)存訪問 | 試圖訪問未分配給自己的內(nèi)存,或試圖往沒有寫權(quán)限的內(nèi)存地址寫數(shù)據(jù)。 |
16 | SIGSTKFLT | 棧溢出 | 堆棧溢出。 |
31 | SIGSYS | 系統(tǒng)調(diào)用異常 | 非法的系統(tǒng)調(diào)用。 |
使用說明
進(jìn)程崩潰日志生成
目前已默認(rèn)開啟,進(jìn)程因上述異常信號崩潰將會在設(shè)備 /data/log/faultlog/temp
目錄下生成完整的崩潰日志,可基于該崩潰日志進(jìn)行問題定位可分析。
DumpCatcher 接口
DumpCatcher是提供給第三方模塊使用的抓取調(diào)用?;A(chǔ)庫,其中包含了打印指定進(jìn)程(或線程)的棧信息的接口函數(shù)。目前支持CPP調(diào)用棧和CPP-JS混合棧。
接口類名:DfxDumpCatcher
接口定義:
- 默認(rèn):
bool DumpCatch(int pid, int tid, std::string& msg);
- 支持混合棧:
bool DumpCatchMix(int pid, int tid, std::string& msg);
- 支持輸出到指定文件:
bool DumpCatchFd(int pid, int tid, std::string& msg, int fd);
- 支持批量抓棧:
bool DumpCatchMultiPid(const std::vector
pidV, std::string& msg);
接口參數(shù)說明:
- 接口返回值:
true
:回棧成功,回棧信息存儲在msg
字符串對象中;false
:回棧失敗。
- 輸入?yún)?shù):
pid
:希望回棧的進(jìn)程號,如果需要回棧進(jìn)程中的所有線程,則tid
設(shè)定為0
;tid
:希望回棧的線程號;fd
:指定寫入回棧信息的文件句柄;
- 輸出參數(shù):
msg
:如果回棧成功,則通過msg
輸出回棧后的信息。
注意:此接口需要調(diào)用者是管理員(system,root)用戶,或者只抓取自己用戶擁有的進(jìn)程信息。
樣例代碼:
- dump_catcher_demo.h
#ifndef DUMP_CATCHER_DEMO_H
#define DUMP_CATCHER_DEMO_H
#include < inttypes.h >
#define NOINLINE __attribute__((noinline))
#define GEN_TEST_FUNCTION(FuncNumA, FuncNumB)
__attribute__((noinline)) int TestFunc##FuncNumA()
{
return TestFunc##FuncNumB();
}
// test functions for callstack depth test
int TestFunc0(void);
int TestFunc1(void);
int TestFunc2(void);
int TestFunc3(void);
int TestFunc4(void);
int TestFunc5(void);
int TestFunc6(void);
int TestFunc7(void);
int TestFunc8(void);
int TestFunc9(void);
int TestFunc10(void);
#endif // DUMP_CATCHER_DEMO_H
- dump_catcher_demo.cpp
#include "dump_catcher_demo.h"
#include < iostream >
#include < string >
#include < unistd.h >
#include "dfx_dump_catcher.h"
using namespace std;
NOINLINE int TestFunc10(void)
{
OHOS::HiviewDFX::DfxDumpCatcher dumplog;
string msg = "";
bool ret = dumplog.DumpCatch(getpid(), gettid(), msg);
if (ret) {
cout < < msg < < endl;
}
return 0;
}
// auto gen function
GEN_TEST_FUNCTION(0, 1)
GEN_TEST_FUNCTION(1, 2)
GEN_TEST_FUNCTION(2, 3)
GEN_TEST_FUNCTION(3, 4)
GEN_TEST_FUNCTION(4, 5)
GEN_TEST_FUNCTION(5, 6)
GEN_TEST_FUNCTION(6, 7)
GEN_TEST_FUNCTION(7, 8)
GEN_TEST_FUNCTION(8, 9)
GEN_TEST_FUNCTION(9, 10)
int main(int argc, char *argv[])
{
TestFunc0();
return 0;
}
- BUILD.gn:
import("http://base/hiviewdfx/faultloggerd/faultloggerd.gni")
import("http://build/ohos.gni")
config("dumpcatcherdemo_config") {
visibility = [ ":*" ]
include_dirs = [
".",
"http://utils/native/base/include",
"http://base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher/include/",
]
}
ohos_executable("dumpcatcherdemo") {
sources = [ "dump_catcher_demo.cpp" ]
configs = [ ":dumpcatcherdemo_config" ]
deps = [
"http://base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher:libdfx_dumpcatcher",
"http://utils/native/base:utils",
]
external_deps = [ "hilog:libhilog" ]
install_enable = true
part_name = "faultloggerd"
subsystem_name = "hiviewdfx"
}
- 執(zhí)行結(jié)果:
# ./dumpcatcherdemo
#00 pc 0000000000000981(00000000004a8981) /data/test/dumpcatcherdemo
#01 pc 0000000000000a6d(00000000004a8a6d) /data/test/dumpcatcherdemo
#02 pc 0000000000000a63(00000000004a8a63) /data/test/dumpcatcherdemo
#03 pc 0000000000000a59(00000000004a8a59) /data/test/dumpcatcherdemo
#04 pc 0000000000000a4f(00000000004a8a4f) /data/test/dumpcatcherdemo
#05 pc 0000000000000a45(00000000004a8a45) /data/test/dumpcatcherdemo
#06 pc 0000000000000a3b(00000000004a8a3b) /data/test/dumpcatcherdemo
#07 pc 0000000000000a31(00000000004a8a31) /data/test/dumpcatcherdemo
#08 pc 0000000000000a27(00000000004a8a27) /data/test/dumpcatcherdemo
#09 pc 0000000000000a1d(00000000004a8a1d) /data/test/dumpcatcherdemo
#10 pc 0000000000000a13(00000000004a8a13) /data/test/dumpcatcherdemo
#11 pc 0000000000000a77(00000000004a8a77) /data/test/dumpcatcherdemo
#12 pc 00000000000c2b08(00000000b6fafb08) /system/lib/ld-musl-arm.so.1(__libc_start_main+116)
#13 pc 0000000000000938(00000000004a8938) /data/test/dumpcatcherdemo
#14 pc 00000000000008c4(00000000004a88c4) /data/test/dumpcatcherdemo
DumpCatcher 命令行工具
DumpCatcher 是指提供給用戶的一個抓取調(diào)用棧命令行工具,由 DumpCatcher innerkits 接口封裝實現(xiàn),該工具通過 -p
、-t
參數(shù)指定進(jìn)程和線程,以及 [-c -m -k]
可選參數(shù)指定抓棧的類型,命令執(zhí)行后在命令行窗口打印指定的進(jìn)程的線程棧信息。
工具名稱:dumpcatcher
位置:/system/bin
參數(shù)說明:
-p [pid]
:打印指定進(jìn)程下面的所有線程棧信息;-p [pid] -t [tid]
:打印指定進(jìn)程下面的指定線程信息。[-c -m -k]
:可選參數(shù), 指定打印-c(pp)
C++調(diào)用棧、-m(ix)
C++ JS混合調(diào)用棧、-k(ernel)
調(diào)用棧類型。
返回打印說明:如果棧信息解析成功,則將信息顯示到標(biāo)準(zhǔn)輸出。
注意:使用此接口需要調(diào)用者是管理員(system,root)用戶。
Rust Panic 故障處理器
TODO
處理流程
進(jìn)程崩潰抓棧處理流程
- 進(jìn)程運行時異常崩潰后會收到來自
Kernel
發(fā)送的崩潰信號,由進(jìn)程在啟動加載的SignalHandler
模塊進(jìn)行信號處理; - 進(jìn)程接收到崩潰信號后,保存當(dāng)前進(jìn)程上下文,fork 出子進(jìn)程執(zhí)行
ProcessDump
二進(jìn)制進(jìn)行抓棧; ProcessDump
向Faultloggerd
申請文件句柄用于存儲收集到的崩潰日志數(shù)據(jù);ProcesDump
將完整崩潰日志數(shù)據(jù)寫入到/data/log/faultlog/temp
目錄下進(jìn)行臨時存儲;ProcessDump
收集完崩潰日志后,上報給Hiview
進(jìn)行后續(xù)處理;Hiview
接收到新增進(jìn)程崩潰故障數(shù)據(jù)后,提取簡易的崩潰日志存儲到/data/log/faultlog/faultlogger
目錄下,并生成HiSysevent
故障事件。
DumpCatcher 接口/命令行工具 主動抓棧處理流程
- 進(jìn)程A調(diào)用
DumpCatcher
庫提供的系列接口(1B),或通過DumpCatcher
命令行工具(1A),申請dump指定進(jìn)程和線程的堆棧信息; - 如果目前進(jìn)程是當(dāng)前進(jìn)程,則直接調(diào)用
BackTrace Local
提供的能力進(jìn)行本地回棧輸出(2B);如果不是,則向Faultloggerd
服務(wù)發(fā)送抓棧請求(2A); Faultloggerd
接收到抓棧請求,鑒通過權(quán)和管道申請等操作后,向目標(biāo)進(jìn)程發(fā)送SIGDUMP(35)
信號觸發(fā)主動抓棧(3);- 目前進(jìn)程接收到
SIGDUMP(35)
抓棧信號后,保存當(dāng)前進(jìn)程上下文,fork出子進(jìn)程執(zhí)行ProcessDump
二進(jìn)制進(jìn)行抓棧,通過Faultloggerd
申請到的管道返回調(diào)用棧數(shù)據(jù)(4)。
Rust Panic 故障日志收集流程
// TODO
審核編輯 黃宇
-
處理器
+關(guān)注
關(guān)注
68文章
19100瀏覽量
228814 -
Rust
+關(guān)注
關(guān)注
1文章
228瀏覽量
6542 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2302瀏覽量
42689
發(fā)布評論請先 登錄
相關(guān)推薦
評論