1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cppcrash_reporter.h"
17
18 #include <cinttypes>
19 #include <dlfcn.h>
20 #include <map>
21 #include <string>
22 #include "dfx_logger.h"
23 #include "dfx_process.h"
24 #include "dfx_signal.h"
25 #include "dfx_thread.h"
26
27 struct FaultLogInfoInner {
28 uint64_t time {0};
29 uint32_t id {0};
30 int32_t pid {-1};
31 int32_t faultLogType {0};
32 std::string module;
33 std::string reason;
34 std::string summary;
35 std::string logPath;
36 std::map<std::string, std::string> sectionMaps;
37 };
38 static const char FOUNDATION_PROCESS_NAME[] = "foundation";
39 static const char HIVIEW_PROCESS_NAME[] = "/system/bin/hiview";
40
41 using AddFaultLog = void (*)(FaultLogInfoInner* info);
42 using RecordAppExitReason = int (*)(int reason);
43
44 namespace OHOS {
45 namespace HiviewDFX {
46
Format()47 bool CppCrashReporter::Format()
48 {
49 if (process_ == nullptr) {
50 return false;
51 }
52
53 cmdline_ = process_->processInfo_.processName;
54 pid_ = process_->processInfo_.pid;
55 uid_ = process_->processInfo_.uid;
56 reason_ = DfxSignal::PrintSignal(siginfo_);
57 auto msg = process_->GetFatalMessage();
58 if (!msg.empty()) {
59 stack_ = "LastFatalMessage:" + msg + "\n";
60 }
61
62 if (process_->vmThread_ != nullptr) {
63 std::string threadInfo = process_->vmThread_->ToString();
64 auto iterator = threadInfo.begin();
65 while (iterator != threadInfo.end() && *iterator != '\n') {
66 if (isdigit(*iterator)) {
67 iterator = threadInfo.erase(iterator);
68 } else {
69 iterator++;
70 }
71 }
72 stack_ += threadInfo;
73 }
74 return true;
75 }
76
ReportToHiview()77 void CppCrashReporter::ReportToHiview()
78 {
79 if (!Format()) {
80 DFXLOG_WARN("Failed to format crash report.");
81 return;
82 }
83 if (process_->processInfo_.processName.find(HIVIEW_PROCESS_NAME) != std::string::npos) {
84 DFXLOG_WARN("Failed to report, hiview is crashed.");
85 return;
86 }
87
88 void* handle = dlopen("libfaultlogger.z.so", RTLD_LAZY | RTLD_NODELETE);
89 if (handle == nullptr) {
90 DFXLOG_WARN("Failed to dlopen libfaultlogger, %s\n", dlerror());
91 return;
92 }
93
94 AddFaultLog addFaultLog = (AddFaultLog)dlsym(handle, "AddFaultLog");
95 if (addFaultLog == nullptr) {
96 DFXLOG_WARN("Failed to dlsym AddFaultLog, %s\n", dlerror());
97 dlclose(handle);
98 return;
99 }
100
101 FaultLogInfoInner info;
102 info.time = time_;
103 info.id = uid_;
104 info.pid = pid_;
105 info.faultLogType = 2; // 2 : CPP_CRASH_TYPE
106 info.module = cmdline_;
107 info.reason = reason_;
108 info.summary = stack_;
109 info.sectionMaps = kvPairs_;
110 addFaultLog(&info);
111 DFXLOG_INFO("Finish report fault to FaultLogger %s(%d,%d)", cmdline_.c_str(), pid_, uid_);
112 dlclose(handle);
113 }
114
ReportToAbilityManagerService()115 void CppCrashReporter::ReportToAbilityManagerService()
116 {
117 if (process_->processInfo_.processName.find(FOUNDATION_PROCESS_NAME) != std::string::npos) {
118 DFXLOG_WARN("Do not to report to AbilityManagerService, foundation is crashed.");
119 return;
120 }
121
122 void* handle = dlopen("libability_manager_c.z.so", RTLD_LAZY | RTLD_NODELETE);
123 if (handle == nullptr) {
124 DFXLOG_WARN("Failed to dlopen libabilityms, %s\n", dlerror());
125 return;
126 }
127
128 RecordAppExitReason recordAppExitReason = (RecordAppExitReason)dlsym(handle, "RecordAppExitReason");
129 if (recordAppExitReason == nullptr) {
130 DFXLOG_WARN("Failed to dlsym RecordAppExitReason, %s\n", dlerror());
131 dlclose(handle);
132 return;
133 }
134
135 // defined in interfaces/inner_api/ability_manager/include/ability_state.h
136 const int cppCrashExitReason = 2;
137 recordAppExitReason(cppCrashExitReason);
138 dlclose(handle);
139 }
140 } // namespace HiviewDFX
141 } // namespace OHOS
142