• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ = PrintSignal(siginfo_);
56     auto msg =  "LastFatalMessage:" + process_->GetFatalMessage();
57     if (siginfo_.si_signo == SIGABRT && !msg.empty()) {
58         stack_ = msg + "\n";
59     }
60     auto threads = process_->GetThreads();
61     std::shared_ptr<DfxThread> crashThread = nullptr;
62     if (!threads.empty()) {
63         crashThread = threads.front();
64     }
65     if (crashThread != nullptr) {
66         stack_ += crashThread->ToString();
67     }
68     return true;
69 }
70 
ReportToHiview()71 void CppCrashReporter::ReportToHiview()
72 {
73     if (!Format()) {
74         DfxLogWarn("Failed to format crash report.");
75         return;
76     }
77     if (process_->GetProcessName().find(HIVIEW_PROCESS_NAME) != std::string::npos) {
78         DfxLogWarn("Failed to report, hiview is crashed.");
79         return;
80     }
81 
82     void* handle = dlopen("libfaultlogger.z.so", RTLD_LAZY | RTLD_NODELETE);
83     if (handle == nullptr) {
84         DfxLogWarn("Failed to dlopen libfaultlogger, %s\n", dlerror());
85         return;
86     }
87 
88     AddFaultLog addFaultLog = (AddFaultLog)dlsym(handle, "AddFaultLog");
89     if (addFaultLog == nullptr) {
90         DfxLogWarn("Failed to dlsym AddFaultLog, %s\n", dlerror());
91         dlclose(handle);
92         return;
93     }
94 
95     FaultLogInfoInner info;
96     info.time = time_;
97     info.id = uid_;
98     info.pid = pid_;
99     info.faultLogType = 2; // 2 : CPP_CRASH_TYPE
100     info.module = cmdline_;
101     info.reason = reason_;
102     info.summary = stack_;
103     info.sectionMaps = kvPairs_;
104     addFaultLog(&info);
105     DfxLogInfo("Finish report fault to FaultLogger %s(%d,%d)", cmdline_.c_str(), pid_, uid_);
106     dlclose(handle);
107 }
108 } // namespace HiviewDFX
109 } // namespace OHOS
110