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 #include "log_util.h"
16
17 #include <cstring>
18 #include <fcntl.h>
19 #include <fstream>
20 #include <sstream>
21 #include <unistd.h>
22
23 #include "file_util.h"
24 #include "hiview_logger.h"
25 #include "string_util.h"
26
27 using namespace std;
28 namespace OHOS {
29 namespace HiviewDFX {
30 DEFINE_LOG_TAG("LogUtil");
31
32 // define Fdsan Domain
33 #ifndef FDSAN_DOMAIN
34 #undef FDSAN_DOMAIN
35 #endif
36 #define FDSAN_DOMAIN 0xD002D11
37
38 namespace {
39 const int BUF_LEN_2048 = 2048;
40 const int TOTAL_SKIP_NUM = 4;
41 }
42
43 /* GetTrace function:
44 * buffer : log buffer
45 * cursor : buffer seekg
46 * reg : regex which is used to get trace line
47 * result : all trace line will be spliced by "\n"
48 * startReg : start place when regex is match, default empty string
49 */
GetTrace(stringstream & buffer,int cursor,const string & reg,string & result,string startReg)50 void LogUtil::GetTrace(stringstream& buffer, int cursor, const string& reg, string& result, string startReg)
51 {
52 buffer.seekg(cursor, ios::beg);
53 string line;
54 bool start = false;
55 int num = 0;
56 int skipNum = 0;
57 startReg = startReg.empty() ? reg : startReg;
58
59 while (getline(buffer, line) && num++ < TOTAL_LINE_NUM) {
60 if (line.length() > BUF_LEN_2048) {
61 continue;
62 }
63 if (line.size() == 0 || skipNum >= TOTAL_SKIP_NUM) {
64 break; // blank line
65 }
66 if (!start) {
67 start = regex_search(line, regex(startReg));
68 if (!start) {
69 continue;
70 }
71 }
72
73 smatch matches;
74 if (regex_search(line, matches, regex(reg))) {
75 skipNum = 0;
76 result += matches.str(0) + LogUtil::SPLIT_PATTERN;
77 continue;
78 }
79
80 if (regex_match(line, matches, regex("^Tid:\\d+, Name:.*$"))) {
81 break; // match new thread break
82 }
83
84 skipNum++;
85 }
86 }
87
ReadFileBuff(const string & file,stringstream & buffer)88 bool LogUtil::ReadFileBuff(const string& file, stringstream& buffer)
89 {
90 int fd = LogUtil::GetFileFd(file);
91 if (fd < 0) {
92 HIVIEW_LOGE("%{public}s get fd fail, fd is %{public}d.", file.c_str(), fd);
93 return false;
94 }
95
96 std::string content;
97 if (!FileUtil::LoadStringFromFd(fd, content)) {
98 HIVIEW_LOGE("read file: %s failed, fd is %d\n", file.c_str(), fd);
99 fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, FDSAN_DOMAIN));
100 return false;
101 }
102 buffer.str(content);
103 fdsan_close_with_tag(fd, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, FDSAN_DOMAIN));
104 return true;
105 }
106
GetFileFd(const string & file)107 int LogUtil::GetFileFd(const string& file)
108 {
109 if (file.empty() || !FileUtil::IsLegalPath(file)) {
110 HIVIEW_LOGE("the system file (%{public}s) is illegal.", file.c_str());
111 return -1;
112 }
113 std::string realFileName;
114 if (!FileUtil::PathToRealPath(file, realFileName) || realFileName.empty() ||
115 !FileUtil::FileExists(realFileName)) {
116 HIVIEW_LOGE("the system file (%{public}s) is not found.", realFileName.c_str());
117 return -1;
118 }
119 int fd = open(realFileName.c_str(), O_RDONLY);
120 if (fd >= 0) {
121 fdsan_exchange_owner_tag(fd, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, FDSAN_DOMAIN));
122 }
123 return fd;
124 }
125
FileExist(const string & file)126 bool LogUtil::FileExist(const string& file)
127 {
128 return FileUtil::FileExists(file);
129 }
130
IsTestModel(const string & sourceFile,const string & name,const string & pattern,string & desPath)131 bool LogUtil::IsTestModel(const string& sourceFile, const string& name,
132 const string& pattern, string& desPath)
133 {
134 if (FileUtil::IsDirectory(LogUtil::SMART_PARSER_TEST_DIR)) {
135 HIVIEW_LOGI("test dir exist.");
136 std::string sourceFileName = StringUtil::GetRrightSubstr(sourceFile, "/");
137 std::string dirOrFileName = StringUtil::GetRrightSubstr(name, "/");
138 std::string fileName = pattern.find("/") != std::string::npos ?
139 StringUtil::GetRrightSubstr(pattern, "/") : pattern;
140 smatch result;
141 if (regex_match(sourceFileName, result, regex(dirOrFileName)) ||
142 regex_match(sourceFileName, result, regex(fileName))) {
143 return LogUtil::FileExist(desPath);
144 }
145 return false;
146 }
147 return false;
148 }
149 } // namespace HiviewDFX
150 } // namespace OHOS
151