• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "dfx_ring_buffer_wrapper.h"
17 
18 #include <securec.h>
19 #include <unistd.h>
20 
21 #include "dfx_define.h"
22 #include "dfx_logger.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 static const int32_t INVALID_FD = -1;
27 static const int32_t UNUSED_FD = -2;
28 std::condition_variable DfxRingBufferWrapper::printCV_;
29 std::mutex DfxRingBufferWrapper::printMutex_;
30 
GetInstance()31 DfxRingBufferWrapper &DfxRingBufferWrapper::GetInstance()
32 {
33     static DfxRingBufferWrapper ins;
34     return ins;
35 }
36 
AppendMsg(const std::string & msg)37 void DfxRingBufferWrapper::AppendMsg(const std::string& msg)
38 {
39     if (writeFunc_ == nullptr) {
40         writeFunc_ = DfxRingBufferWrapper::DefaultWrite;
41     }
42     writeFunc_(fd_, msg.c_str(), msg.length());
43 }
44 
AppendBuf(const char * format,...)45 int DfxRingBufferWrapper::AppendBuf(const char *format, ...)
46 {
47     int ret = -1;
48     char buf[LINE_BUF_SIZE] = {0};
49     va_list args;
50     va_start(args, format);
51     ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, args);
52     va_end(args);
53     if (ret < 0) {
54         DFXLOGE("%{public}s :: vsnprintf_s failed, line: %{public}d.", __func__, __LINE__);
55     }
56 
57     AppendMsg(std::string(buf));
58     return ret;
59 }
60 
SplitDumpInfo(const std::string & dumpInfo,const std::string & sepator)61 static std::vector<std::string> SplitDumpInfo(const std::string& dumpInfo, const std::string& sepator)
62 {
63     std::vector<std::string> result;
64     if (dumpInfo.empty() || sepator.empty()) {
65         return result;
66     }
67     size_t begin = 0;
68     size_t pos = dumpInfo.find(sepator, begin);
69     while (pos != std::string::npos) {
70         result.push_back(dumpInfo.substr(begin, pos - begin));
71 
72         begin = pos + sepator.size();
73         pos = dumpInfo.find(sepator, begin);
74     }
75     if (begin < dumpInfo.size()) {
76         result.push_back(dumpInfo.substr(begin));
77     }
78     return result;
79 }
80 
AppendBaseInfo(const std::string & info)81 void DfxRingBufferWrapper::AppendBaseInfo(const std::string& info)
82 {
83     crashBaseInfo_.emplace_back(info);
84 }
85 
PrintBaseInfo()86 void DfxRingBufferWrapper::PrintBaseInfo()
87 {
88     if (crashBaseInfo_.empty()) {
89         DFXLOGE("crash base info is empty");
90     }
91     for (const auto& item : crashBaseInfo_) {
92         std::vector<std::string> itemVec = SplitDumpInfo(item, "\n");
93         for (size_t i = 0; i < itemVec.size(); i++) {
94             DFXLOGI("%{public}s", itemVec[i].c_str());
95         }
96     }
97 }
98 
StartThread()99 void DfxRingBufferWrapper::StartThread()
100 {
101     hasFinished_ = false;
102 }
103 
StopThread()104 void DfxRingBufferWrapper::StopThread()
105 {
106     if (fd_ != INVALID_FD) {
107         if (fsync(fd_) == -1) {
108             DFXLOGW("Failed to fsync fd.");
109         }
110         close(fd_);
111     }
112     fd_ = INVALID_FD;
113 }
114 
SetWriteBufFd(int32_t fd)115 void DfxRingBufferWrapper::SetWriteBufFd(int32_t fd)
116 {
117     fd_ = fd;
118     if (fd_ < 0) {
119         DFXLOGW("%{public}s :: Failed to set fd.\n", __func__);
120     }
121 }
122 
SetWriteFunc(RingBufferWriteFunc func)123 void DfxRingBufferWrapper::SetWriteFunc(RingBufferWriteFunc func)
124 {
125     writeFunc_ = func;
126 }
127 
DefaultWrite(int32_t fd,const char * buf,const int len)128 int DfxRingBufferWrapper::DefaultWrite(int32_t fd, const char *buf, const int len)
129 {
130     if (buf == nullptr) {
131         return -1;
132     }
133     WriteLog(UNUSED_FD, "%s", buf);
134     if (fd > 0) {
135         return OHOS_TEMP_FAILURE_RETRY(write(fd, buf, len));
136     }
137     return 0;
138 }
139 } // namespace HiviewDFX
140 } // namespace OHOS
141