1 /*
2 * Copyright (c) 2021 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 /* This files is writer log to file module on process dump module. */
17
18 #include "cppcrash_reporter.h"
19
20 #include <cinttypes>
21 #include <dlfcn.h>
22 #include <map>
23 #include <string>
24 #include "dfx_logger.h"
25 #include "dfx_process.h"
26 #include "dfx_signal.h"
27 #include "dfx_thread.h"
28
29 struct FaultLogInfoInner {
30 uint64_t time {0};
31 uint32_t id {0};
32 int32_t pid {-1};
33 int32_t faultLogType {0};
34 std::string module;
35 std::string reason;
36 std::string summary;
37 std::string logPath;
38 std::map<std::string, std::string> sectionMaps;
39 };
40 static const char HIVIEW_PROCESS_NAME[] = "/system/bin/hiview";
41
42 using AddFaultLog = void (*)(FaultLogInfoInner* info);
43 namespace OHOS {
44 namespace HiviewDFX {
45
Format()46 bool CppCrashReporter::Format()
47 {
48 if (process_ == nullptr) {
49 return false;
50 }
51
52 cmdline_ = process_->GetProcessName();
53 pid_ = process_->GetPid();
54 uid_ = process_->GetUid();
55 reason_ = FormatSignalName(signo_);
56 auto threads = process_->GetThreads();
57 std::shared_ptr<DfxThread> crashThread = nullptr;
58 if (!threads.empty()) {
59 crashThread = threads.front();
60 }
61
62 if (crashThread != nullptr) {
63 stack_ = crashThread->ToString();
64 }
65 return true;
66 }
67
ReportToHiview()68 void CppCrashReporter::ReportToHiview()
69 {
70 if (!Format()) {
71 DfxLogWarn("Failed to format crash report.");
72 return;
73 }
74 if (process_->GetProcessName().find(HIVIEW_PROCESS_NAME) != std::string::npos) {
75 DfxLogWarn("Failed to report, hiview is crashed.");
76 return;
77 }
78
79 void* handle = dlopen("libfaultlogger.z.so", RTLD_LAZY | RTLD_NODELETE);
80 if (handle == nullptr) {
81 DfxLogWarn("Failed to dlopen libfaultlogger, %s\n", dlerror());
82 return;
83 }
84
85 AddFaultLog addFaultLog = (AddFaultLog)dlsym(handle, "AddFaultLog");
86 if (addFaultLog == nullptr) {
87 DfxLogWarn("Failed to dlsym AddFaultLog, %s\n", dlerror());
88 dlclose(handle);
89 return;
90 }
91
92 FaultLogInfoInner info;
93 info.time = time_ / 1000;
94 info.id = uid_;
95 info.pid = pid_;
96 info.faultLogType = 2; // 2 : CPP_CRASH_TYPE
97 info.module = cmdline_;
98 info.reason = reason_;
99 info.summary = stack_;
100 info.sectionMaps = kvPairs_;
101 addFaultLog(&info);
102 DfxLogInfo("Finish report fault to FaultLogger %s(%d,%d)", cmdline_.c_str(), pid_, uid_);
103 dlclose(handle);
104 }
105 } // namespace HiviewDFX
106 } // namespace OHOS
107