• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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