# Faultlogger开呿Œ‡å¯¼ ## 概述 ### 功能简介 Faultlogger是OpenHarmony为开å‘者æä¾›çš„一个维测日志框架,能够为应用ã€å…ƒèƒ½åŠ›ã€ç³»ç»ŸæœåŠ¡è¿›ç¨‹å´©æºƒæ•…éšœæä¾›ç»Ÿä¸€æ£€æµ‹ã€æ—¥å¿—é‡‡é›†ã€æ—¥å¿—å˜å‚¨ã€æ—¥å¿—上报功能,为应用崩溃故障æä¾›è¯¦ç»†çš„维测日志用以辅助故障定ä½ã€‚æœ¬ç« èŠ‚å†…å®¹é€‚ç”¨äºŽæ ‡å‡†ç³»ç»Ÿä»¥åŠLinuxå†…æ ¸çš„å°åž‹ç³»ç»Ÿã€‚ FaultLogger承载OpenHarmony系统上的故障记录功能,按照æœåŠ¡å¯¹è±¡ä¸åŒåˆ†åˆ«è¿è¡Œåœ¨ä¸¤ä¸ªéƒ¨ä»¶ä¸ï¼š - Hiview部件ä¸çš„æœåŠ¡ï¼šæœåŠ¡äºŽåº”ç”¨å±‚å’Œnative层的功能模å—,功能是分类管ç†ç³»ç»Ÿä¸å‘生的å„类故障信æ¯ï¼Œå¹¶ä¸ºæ¨¡å—æä¾›æŸ¥è¯¢æ•…障的API。 - Faultloggerd部件ä¸çš„æœåŠ¡ï¼šæœåŠ¡äºŽå´©æºƒè¿›ç¨‹ï¼ŒåŠŸèƒ½æ˜¯æ”¶é›†C/C++è¿è¡Œæ—¶å¼‚常的守护进程和获å–è¿›ç¨‹è°ƒç”¨æ ˆã€‚ 基于FaultloggeræœåŠ¡ï¼Œè¿›ç¨‹å´©æºƒçš„å¤„ç†æµç¨‹å¦‚下图所示: **图1** è¿›ç¨‹å´©æºƒå¤„ç†æµç¨‹å›¾  1. 进程è¿è¡Œæ—¶å´©æºƒï¼Œå†…æ ¸æŠ›å‡ºå´©æºƒä¿¡å·ï¼Œç”¨æˆ·æ€SignalHandlerå“应(进程å¯åŠ¨æ—¶ç¡¬ç¼–ç æ³¨å†Œï¼‰ï¼› 2. SignalHandler收集好崩溃现场信æ¯ï¼ˆcontextã€fatal messageç‰ï¼‰ï¼Œè®¾ç½®å½“å‰è¿›ç¨‹ptracerå’Œdumpable状æ€åŽï¼Œfork出ProcessDump进程进行remoteæŠ“æ ˆï¼› 3. ProcessDump获å–到signalhandler通过pipeä¼ è¾“è¿‡æ¥çš„进程crash现场相关信æ¯åŽï¼Œå‘Faultloggerd申请crashæ–‡ä»¶å¥æŸ„ï¼› 4. 基于libunwinderè‡ªç ”å›žæ ˆèƒ½åŠ›è¿›è¡Œå›žæ ˆï¼Œå´©æºƒæ—¥å¿—å†™å…¥åˆ°`/data/log/faultlog/temp` 目录下的原始crash故障文件; 5. ProcessDump完æˆcrash文件内容写入åŽï¼Œå°†ç²¾ç®€çš„crashæ•…éšœä¿¡æ¯æ‰“包上报到hiviewï¼› 6. hiview faultloggeræ’ä»¶æŽ¥æ”¶åˆ°æ·»åŠ çš„crashä¿¡æ¯åŽï¼Œé¢å¤–获å–hilogä¿¡æ¯ï¼Œåœ¨`/data/log/faultlog/faultlogger`目录下生æˆé¢å‘å¼€å‘者开å‘çš„æ—¥å¿—ã€‚åŒæ—¶ä¸ŠæŠ¥åˆ°hisyseventå’Œhiappeventï¼› ### 使用场景 Faultloggerdæ„在为开å‘è€…åœ¨å¼€å‘æµ‹è¯•过程ä¸é‡åˆ°çš„å´©æºƒæˆ–å¡æ»é—®é¢˜æä¾›ä¸€ç§ç®€å•è½»é‡çš„å®šä½æ‰‹æ®µã€‚ 主è¦åŒ…å«ä»¥ä¸‹åº”用场景: **表1** Faultloggerd模å—应用场景 | 场景æè¿° | 使用工具 | ä½¿ç”¨æ–¹å¼ | | -------- | -------- | -------- | | äº†è§£å‡½æ•°çš„è°ƒç”¨é¡ºåº | DumpCatcher API | å‚è§ï¼š[使用DumpCatcher接å£èŽ·å–è°ƒç”¨æ ˆ](#使用dumpcatcher接å£èŽ·å–è°ƒç”¨æ ˆ) | | åº”ç”¨å¡æ»/CPUå 用高 | DumpCatcher Command Tool | å‚è§ï¼š[使用DumpCatcher命令获å–è°ƒç”¨æ ˆ](#使用dumpcatcher命令获å–è°ƒç”¨æ ˆ) | | å´©æºƒé—®é¢˜å®šä½ | 崩溃日志和llvm-addr2line工具 | å‚è§ï¼š[基于崩溃日志定ä½é—®é¢˜](#基于崩溃日志定ä½é—®é¢˜) | ## 使用DumpCatcher接å£èŽ·å–è°ƒç”¨æ ˆ ### 接å£è¯´æ˜Ž DumpCatcherå¯ä»¥æŠ“å–OpenHarmonyæŒ‡å®šè¿›ç¨‹ï¼ˆçº¿ç¨‹ï¼‰çš„è°ƒç”¨æ ˆã€‚ **表2** DumpCatcher接å£è¯´æ˜Ž | ç±» | 方法 | æè¿° | | -------- | -------- | -------- | | DfxDumpCatcher | bool DumpCatch(const int pid, const int tid, std::string& msg, size_t maxFrameNums, bool isJson) | 接å£è¿”回值:<br/>- trueï¼šå›žæ ˆæˆåŠŸï¼Œå›žæ ˆä¿¡æ¯å˜å‚¨åœ¨msgå—符串对象ä¸ï¼›<br/>- falseï¼šå›žæ ˆå¤±è´¥ã€‚<br/> è¾“å…¥å‚æ•°ï¼š<br/>- pidï¼šç›®æ ‡è¿›ç¨‹å·ï¼›<br/>- tidï¼šç›®æ ‡çº¿ç¨‹å·ï¼Œå¦‚果需è¦å›žæ ˆè¿›ç¨‹ä¸çš„æ‰€æœ‰çº¿ç¨‹ï¼Œåˆ™tid设定为0ï¼›<br/>- maxFrameNumsï¼šå›žæ ˆæœ€å¤§å¸§æ•°ï¼Œå¦‚æžœpidä¸ç‰äºŽè°ƒç”¨æ–¹pidï¼Œåˆ™å¿½ç•¥è¿™ä¸ªå‚æ•°ï¼Œè¯¥å‚数默认值为256ï¼›<br/>- isJsonï¼šå †æ ˆæ¶ˆæ¯æ˜¯å¦ä¸ºJSONæ ¼å¼åŒ–ï¼Œè¯¥å‚æ•°é»˜è®¤å€¼ä¸ºfalseï¼›<br/> è¾“å‡ºå‚æ•°ï¼š<br/>- msgï¼šå¦‚æžœå›žæ ˆæˆåŠŸï¼Œåˆ™é€šè¿‡msgè¿”å›žè°ƒç”¨æ ˆä¿¡æ¯ã€‚ | | DfxDumpCatcher | bool DumpCatchMix(const int pid, const int tid, std::string& msg) | 接å£è¿”回值:<br/>- trueï¼šå›žæ ˆæˆåŠŸï¼Œå›žæ ˆä¿¡æ¯å˜å‚¨åœ¨msgå—符串对象ä¸ï¼›<br/>- falseï¼šå›žæ ˆå¤±è´¥ã€‚<br/> è¾“å…¥å‚æ•°ï¼š<br/>- pidï¼šç›®æ ‡è¿›ç¨‹å·ï¼›<br/>- tidï¼šç›®æ ‡çº¿ç¨‹å·ï¼Œå¦‚果需è¦å›žæ ˆè¿›ç¨‹ä¸çš„æ‰€æœ‰çº¿ç¨‹ï¼Œåˆ™tid设定为0ï¼›<br/> è¾“å‡ºå‚æ•°ï¼š<br/>- msgï¼šå¦‚æžœå›žæ ˆæˆåŠŸï¼Œåˆ™é€šè¿‡msgè¿”å›žæ··åˆæ ˆä¿¡æ¯ã€‚ | | DfxDumpCatcher | bool DumpCatchFd(const int pid, const int tid, std::string& msg, int fd, size_t maxFrameNums) | 接å£è¿”回值:<br/>- trueï¼šå›žæ ˆæˆåŠŸï¼Œå›žæ ˆä¿¡æ¯å˜å‚¨åœ¨msgå—符串对象ä¸ï¼›<br/>- falseï¼šå›žæ ˆå¤±è´¥ã€‚<br/> è¾“å…¥å‚æ•°ï¼š<br/>- pidï¼šç›®æ ‡è¿›ç¨‹å·ï¼›<br/>- tidï¼šç›®æ ‡çº¿ç¨‹å·ï¼Œå¦‚果需è¦å›žæ ˆè¿›ç¨‹ä¸çš„æ‰€æœ‰çº¿ç¨‹ï¼Œåˆ™tid设定为0ï¼›<br/>- fdï¼šæŒ‡å®šå†™å…¥çš„æ–‡ä»¶å¥æŸ„å·ï¼›<br/>- maxFrameNumsï¼šå›žæ ˆæœ€å¤§å¸§æ•°ï¼Œå¦‚æžœpidä¸ç‰äºŽè°ƒç”¨æ–¹pidï¼Œåˆ™å¿½ç•¥è¿™ä¸ªå‚æ•°ï¼Œè¯¥å‚数默认值为256ï¼›<br/> è¾“å‡ºå‚æ•°ï¼š<br/>- msgï¼šå¦‚æžœå›žæ ˆæˆåŠŸï¼Œåˆ™é€šè¿‡msgè¿”å›žè°ƒç”¨æ ˆä¿¡æ¯ã€‚ | | DfxDumpCatcher | bool DumpCatchMultiPid(const std::vector\<int> pidV, std::string& msg) | 接å£è¿”回值:<br/>- trueï¼šå›žæ ˆæˆåŠŸï¼Œå›žæ ˆä¿¡æ¯å˜å‚¨åœ¨msgå—符串对象ä¸ï¼›<br/>- falseï¼šå›žæ ˆå¤±è´¥ã€‚<br/> è¾“å…¥å‚æ•°ï¼š<br/>- pidVï¼šç›®æ ‡è¿›ç¨‹å·åˆ—表;<br/> è¾“å‡ºå‚æ•°ï¼š<br/>- msgï¼šå¦‚æžœå›žæ ˆæˆåŠŸï¼Œåˆ™é€šè¿‡msgè¿”å›žè°ƒç”¨æ ˆä¿¡æ¯ã€‚ | >  **说明:** > å½“è°ƒç”¨æ¤æŽ¥å£çš„进程idä¸Žç›®æ ‡pidä¸ä¸€è‡´æ—¶éœ€è¦è°ƒç”¨è€…是管ç†å‘˜ï¼ˆsystem,root)用户。 ### å¼€å‘实例 系统应用开å‘者å¯ä»¥ç”¨DumpCatcher在自己的应用ä¸èŽ·å–æŒ‡å®šè¿›ç¨‹ï¼ˆçº¿ç¨‹ï¼‰çš„è°ƒç”¨æ ˆã€‚ä¸‹æ–‡ä»¥dumpcatcherdemo模å—使用DumpCatcher基础接å£èŽ·å–è°ƒç”¨æ ˆä½œä¸ºå®žä¾‹è¿›è¡Œè®²è§£ã€‚ 1. ç¼–è¯‘æž„å»ºæ–‡ä»¶æ·»åŠ dumpcatcherä¾èµ–:以`/base/hiviewdfx/faultloggerd/example/BUILD.gn`为例,在include_dirs䏿·»åŠ DfxDumpCatcher头文件路径,并在deps䏿·»åŠ `//base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher:lib_dfx_dump_catcher`模å—ä¾èµ–。 ``` import("//base/hiviewdfx/faultloggerd/faultloggerd.gni") config("dumpcatcherdemo_config") { visibility = [ ":*" ] include_dirs = [ ".", "$faultloggerd_common_path/dfxutil", "$faultloggerd_interfaces_path/common", # æ·»åŠ dumpcatcher头文件路径 ] } ohos_executable("dumpcatcherdemo") { sources = [ "dump_catcher_demo.cpp" ] configs = [ ":dumpcatcherdemo_config" ] deps = [ "$faultloggerd_common_path/dfxlog:dfx_hilog", "$faultloggerd_interfaces_path/innerkits/dump_catcher:libdfx_dumpcatcher", # æ·»åŠ dumpcathcer模å—ä¾èµ– "$faultloggerd_interfaces_path/innerkits/formatter:libjson_stack_formatter", ] external_deps = [ "c_utils:utils", "hilog:libhilog", "jsoncpp:jsoncpp", ] install_enable = true part_name = "faultloggerd" subsystem_name = "hiviewdfx" } ``` 备注(如果其他仓想è¦ä¾èµ–该模å—,è¦é€šè¿‡faultloggerd部件进行ä¾èµ–) ``` external_deps += [ "faultloggerd:libdfx_dumpcatcher", "faultloggerd:libjson_stack_formatter", ] ``` 2. 头文件定义用到的函数:以`/base/hiviewdfx/faultloggerd/example/dump_catcher_demo.h`ä¸ºä¾‹ï¼Œæœ¬æ ·ä¾‹ä»£ç ä¸ï¼Œé€šè¿‡è°ƒç”¨æ ˆæ·±åº¦æµ‹è¯•çš„æµ‹è¯•å‡½æ•°æ¥æž„é€ ä¸€ä¸ªæŒ‡å®šæ·±åº¦çš„è°ƒç”¨æ ˆã€‚ ``` #ifndef DUMP_CATCHER_DEMO_H #define DUMP_CATCHER_DEMO_H #define NOINLINE __attribute__((noinline)) // 定义该å®å‡½æ•°ç”¨äºŽè‡ªåŠ¨ç”Ÿæˆå‡½æ•°è°ƒç”¨é“¾ #define GEN_TEST_FUNCTION(FuncNumA, FuncNumB) \ __attribute__((noinline)) int TestFunc##FuncNumA() \ { \ return TestFunc##FuncNumB(); \ } // è°ƒç”¨æ ˆæ·±åº¦æµ‹è¯•çš„æµ‹è¯•å‡½æ•° 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); #endif // DUMP_CATCHER_DEMO_H ``` 3. åœ¨æºæ–‡ä»¶ä¸è°ƒç”¨DumpCatch接å£ï¼šä»¥`/base/hiviewdfx/faultloggerd/example/dump_catcher_demo.cpp`为例,引用dfx_dump_catcher.h头文件,声明DfxDumpCatcher对象,通过å®å‡½æ•°æž„é€ å‡½æ•°è°ƒç”¨é“¾ï¼Œå¹¶æœ€åŽè°ƒç”¨DumpCatchæŽ¥å£æ–¹æ³•ï¼Œä¼ å…¥éœ€è¦æŠ“å–è°ƒç”¨æ ˆçš„è¿›ç¨‹å·ã€çº¿ç¨‹å·ã€‚ ``` #include "dump_catcher_demo.h" #include <cstdint> #include <cstdlib> #include <cstring> #include <iostream> #include <string> #include <unistd.h> #include "dfx_define.h" #include "dfx_dump_catcher.h" #include "dfx_json_formatter.h" #include "elapsed_time.h" static NOINLINE int TestFuncDump(int32_t pid, int32_t tid, bool isJson) { OHOS::HiviewDFX::DfxDumpCatcher dumplog; std::string msg = ""; OHOS::HiviewDFX::ElapsedTime counter; bool ret = dumplog.DumpCatch(pid, tid, msg, OHOS::HiviewDFX::DEFAULT_MAX_FRAME_NUM, isJson); // 调用DumpCatch接å£èŽ·å–è°ƒç”¨æ ˆ time_t elapsed1 = counter.Elapsed(); if (ret) { std::cout << msg << std::endl; if (isJson) { std::string outStr = ""; OHOS::HiviewDFX::DfxJsonFormatter::FormatJsonStack(msg, outStr); std::cout << outStr << std::endl; } } time_t elapsed2 = counter.Elapsed(); std::cout << "elapsed1: " << elapsed1 << " ,elapsed2: " << elapsed2 << std::endl; return ret; } static NOINLINE int TestFunc10(void) { return TestFuncDump(getpid(), gettid(), false); } // 通过å®å‡½æ•°è‡ªåŠ¨ç”Ÿæˆå‡½æ•°è°ƒç”¨é“¾ 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) static bool ParseParameters(int argc, char *argv[], int32_t &pid, int32_t &tid) { switch (argc) { case 3: if (!strcmp("-p", argv[1])) { pid = atoi(argv[2]); return true; } if (!strcmp("-t", argv[1])) { pid = getpid(); tid = atoi(argv[2]); return true; } break; case 5: if (!strcmp("-p", argv[1])) { pid = atoi(argv[2]); if (!strcmp("-t", argv[3])) { tid = atoi(argv[4]); return true; } } else if (!strcmp("-t", argv[1])) { tid = atoi(argv[2]); if (!strcmp("-p", argv[3])) { pid = atoi(argv[4]); return true; } } break; default: break; } return false; } int main(int argc, char *argv[]) { int32_t pid = 0; int32_t tid = 0; if (ParseParameters(argc, argv, pid, tid)) { TestFuncDump(pid, tid, true); } else { TestFunc0(); } return 0; } ``` ## 使用DumpCatcher命令获å–è°ƒç”¨æ ˆ ### 工具说明 DumpCatcher Command Tool是一个抓å–è°ƒç”¨æ ˆçš„å‘½ä»¤è¡Œå·¥å…·ï¼Œåœ¨OpenHarmony系统ä¸å¯ç›´æŽ¥ä½¿ç”¨ï¼Œè¯¥å·¥å…·é€šè¿‡-pã€-t傿•°æŒ‡å®šè¿›ç¨‹å’Œçº¿ç¨‹ï¼Œå‘½ä»¤æ‰§è¡ŒåŽåœ¨å‘½ä»¤è¡Œçª—壿‰“å°æŒ‡å®šè¿›ç¨‹çš„çº¿ç¨‹æ ˆä¿¡æ¯ã€‚还å¯é€šè¿‡æ·»åŠ -m傿•°æ¥æŠ“å–应用进程的JS Nativeæ··åˆæ ˆã€‚ **表3** DumpCatcher Command Tool使用说明 | 工具åç§° | 命令行工具路径 | 执行命令 | æè¿° | | -------- | -------- | -------- | -------- | | dumpcatcher | /system/bin | - dumpcatcher -p [pid]<br/>- dumpcatcher -p [pid] -t [tid]<br/>- dumpcatcher -m -p [pid]<br/>- dumpcatcher -m -p [pid] -t [tid]<br/> | **傿•°è¯´æ˜Žï¼š**<br/>- -p [pid]ï¼šæ‰“å°æŒ‡å®šè¿›ç¨‹ä¸‹é¢çš„æ‰€æœ‰çº¿ç¨‹æ ˆä¿¡æ¯ã€‚<br/>- -p [pid] -t [tid]ï¼šæ‰“å°æŒ‡å®šè¿›ç¨‹ä¸‹é¢çš„æŒ‡å®šçº¿ç¨‹ä¿¡æ¯ã€‚<br/>- -m -p [pid]ï¼šæ‰“å°æŒ‡å®šè¿›ç¨‹ä¸‹é¢çš„æ‰€æœ‰çº¿ç¨‹æ··åˆæ ˆä¿¡æ¯ã€‚<br/>- -m -p [pid] -t [tid]ï¼šæ‰“å°æŒ‡å®šè¿›ç¨‹ä¸‹é¢çš„æŒ‡å®šçº¿ç¨‹æ··åˆæ ˆä¿¡æ¯ã€‚<br/>**返回值说明:**<br/>å¦‚æžœæ ˆä¿¡æ¯è§£æžæˆåŠŸï¼Œåˆ™å°†ä¿¡æ¯æ˜¾ç¤ºåˆ°æ ‡å‡†è¾“出;失败则打å°é”™è¯¯ä¿¡æ¯ã€‚ | ### 使用实例 通过dumpcatcher命令打å°hiviewè¿›ç¨‹çš„è°ƒç”¨æ ˆã€‚ ``` # ps -ef |grep hiview hiview 2035 1 4 14:15:51 ? 00:08:24 hiview root 6428 6425 12 17:31:51 pts/1 00:00:00 grep hiview # dumpcatcher -p 2035 -t 2035 Result: 0 ( no error ) Timestamp:2024-05-06 17:32:05.000 Pid:2035 Uid:1201 Process name:/system/bin/hiview Tid:2035, Name:hiview #00 pc 000c3cac /system/lib/ld-musl-arm.so.1(ioctl+72)(d820b1827e57855d4f9ed03ba5dfea83) #01 pc 0000efdf /system/lib/chipset-pub-sdk/libipc_common.z.so(OHOS::BinderConnector::WriteBinder(unsigned long, void*)+14)(cd26d6fe1883c088fa265a1eb112cd38) #02 pc 000129b1 /system/lib/chipset-pub-sdk/libipc_single.z.so(OHOS::IPC_SINGLE::BinderInvoker::TransactWithDriver(bool)+216)(0d33aaefbd1542c521978a6b2a5e3591) #03 pc 00012aab /system/lib/chipset-pub-sdk/libipc_single.z.so(OHOS::IPC_SINGLE::BinderInvoker::StartWorkLoop()+34)(0d33aaefbd1542c521978a6b2a5e3591) #04 pc 00013abf /system/lib/chipset-pub-sdk/libipc_single.z.so(OHOS::IPC_SINGLE::BinderInvoker::JoinThread(bool)+34)(0d33aaefbd1542c521978a6b2a5e3591) #05 pc 00028df7 /system/bin/hiview(OHOS::HiviewDFX::HiviewService::StartService()+14)(9db8e6c0a2e9e1f6f489bd2b0ddb432c) #06 pc 00012d8d /system/bin/hiview(main+140)(9db8e6c0a2e9e1f6f489bd2b0ddb432c) #07 pc 00072b98 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(d820b1827e57855d4f9ed03ba5dfea83) #08 pc 00012ce8 /system/bin/hiview(_start_c+84)(9db8e6c0a2e9e1f6f489bd2b0ddb432c) #09 pc 00012c8c /system/bin/hiview(9db8e6c0a2e9e1f6f489bd2b0ddb432c) ``` ## 基于崩溃日志定ä½é—®é¢˜ å¼€å‘者å¯ä»¥é€šè¿‡faultloggerd生æˆçš„å´©æºƒå †æ ˆæ—¥å¿—è¿›è¡Œé—®é¢˜å®šä½ã€‚æœ¬ç« èŠ‚å°†ä¸»è¦ä»‹ç»å¦‚何利用llvm-addr2line工具进行崩溃问题定ä½ã€‚ 1. 程åºè‡ªå´©æºƒæˆ–æž„é€ å´©æºƒã€‚ ä¾‹å¦‚å°†å¦‚ä¸‹ä»£ç æ¤å…¥è‡ªå·±çš„代ç ä¸ï¼Œè°ƒç”¨è§¦å‘ä¸€ä¸ªæ— æ•ˆå†…å˜è®¿é—®æ•…障(SIGSEGV)。 ``` NOINLINE int TriggerSegmentFaultException() { printf("test TriggerSegmentFaultException \n"); // ä¸ºæž„é€ å´©æºƒï¼Œå¼ºåˆ¶è¿›è¡Œç±»åž‹è½¬æ¢ int *a = (int *)(&RaiseAbort); *a = SIGSEGV; return 0; } ``` 2. 获å–å´©æºƒå‡½æ•°è°ƒç”¨æ ˆæ—¥å¿—ã€‚ å› ä¸ºå˜åœ¨æœªå¤„ç†çš„异常,进程会在`/data/log/faultlog/temp`路径下生æˆä¸´æ—¶çš„æ—¥å¿—文件,其命å规则为: ``` cppcrash-pid-time ``` 获å–其生æˆçš„è°ƒç”¨æ ˆå¦‚ä¸‹ï¼š ``` Timestamp:2017-08-05 17:35:03.000 Pid:816 Uid:0 Process name:./crasher_c Process life time:1s Reason:Signal:SIGSEGV(SEGV_ACCERR)@0x0042d33d Fault thread Info: Tid:816, Name:crasher #00 pc 0000332c /data/crasher(TriggerSegmentFaultException+15)(8bc37ceb8d6169e919d178fdc7f5449e) #01 pc 000035c7 /data/crasher(ParseAndDoCrash+277)(8bc37ceb8d6169e919d178fdc7f5449e) #02 pc 00003689 /data/crasher(main+39)(8bc37ceb8d6169e919d178fdc7f5449e) #03 pc 000c3b08 /system/lib/ld-musl-arm.so.1(__libc_start_main+116) #04 pc 000032f8 /data/crasher(_start_c+112)(8bc37ceb8d6169e919d178fdc7f5449e) #05 pc 00003284 /data/crasher(_start+32)(8bc37ceb8d6169e919d178fdc7f5449e) Registers: r0:0042d33d r1:0000000b r2:1725d4c4 r3:b6f9fa84 r4:bec97e69 r5:b6fc0268 r6:0042d661 r7:bec97d60 r8:00000000 r9:00000000 r10:00000000 fp:bec97d20 ip:00000020 sp:bec97cd0 lr:b6f9fae4 pc:0042d32c ``` 3. 利用llvm-addr2lineå·¥å…·è¿›è¡Œè°ƒç”¨æ ˆåˆ†æžã€‚ 使用llvm-addr2lineå·¥å…·æ ¹æ®å移地å€è§£æžè¡Œå·: ``` root:~/OpenHarmony/out/hi3516dv300/exe.unstripped/hiviewdfx/faultloggerd$ llvm-addr2line -e crasher 0000332c base/hiviewdfx/faultloggerd/tools/crasher/dfx_crasher.c:57 ``` 这个崩溃是由赋值给一å—ä¸å¯å†™çš„区域导致的,代ç 行为dfx_crasher.c文件的57行,修改åŽå¯ä»¥é¿å…å‘生æ¤å´©æºƒã€‚