1 /*
2 * Copyright (c) 2022 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 "xcollie_utils.h"
17 #include <ctime>
18
19 #include <algorithm>
20 #include <cstdlib>
21 #include <unistd.h>
22 #include "parameter.h"
23
24 namespace OHOS {
25 namespace HiviewDFX {
GetCurrentTickMillseconds()26 uint64_t GetCurrentTickMillseconds()
27 {
28 struct timespec t;
29 t.tv_sec = 0;
30 t.tv_nsec = 0;
31 clock_gettime(CLOCK_MONOTONIC, &t);
32 return (int64_t)((t.tv_sec) * SEC_TO_MANOSEC + t.tv_nsec) / SEC_TO_MICROSEC;
33 }
34
IsFileNameFormat(char c)35 bool IsFileNameFormat(char c)
36 {
37 if (c >= '0' && c <= '9') {
38 return false;
39 }
40
41 if (c >= 'a' && c <= 'z') {
42 return false;
43 }
44
45 if (c >= 'A' && c <= 'Z') {
46 return false;
47 }
48
49 if (c == '.' || c == '-' || c == '_') {
50 return false;
51 }
52
53 return true;
54 }
55
GetSelfProcName()56 std::string GetSelfProcName()
57 {
58 constexpr uint16_t READ_SIZE = 128;
59 std::ifstream fin;
60 fin.open("/proc/self/comm", std::ifstream::in);
61 if (!fin.is_open()) {
62 XCOLLIE_LOGE("fin.is_open() false");
63 return "";
64 }
65 char readStr[READ_SIZE] = {'\0'};
66 fin.getline(readStr, READ_SIZE - 1);
67 fin.close();
68
69 std::string ret = std::string(readStr);
70 ret.erase(std::remove_if(ret.begin(), ret.end(), IsFileNameFormat), ret.end());
71 return ret;
72 }
73
GetFirstLine(const std::string & path)74 std::string GetFirstLine(const std::string& path)
75 {
76 char checkPath[PATH_MAX] = {0};
77 if (realpath(path.c_str(), checkPath) == nullptr) {
78 XCOLLIE_LOGE("canonicalize failed. path is %{public}s", path.c_str());
79 return "";
80 }
81
82 std::ifstream inFile(checkPath);
83 if (!inFile) {
84 return "";
85 }
86 std::string firstLine;
87 getline(inFile, firstLine);
88 inFile.close();
89 return firstLine;
90 }
91
GetProcessNameFromProcCmdline(int32_t pid)92 std::string GetProcessNameFromProcCmdline(int32_t pid)
93 {
94 std::string procCmdlinePath = "/proc/" + std::to_string(pid) + "/cmdline";
95 std::string procCmdlineContent = GetFirstLine(procCmdlinePath);
96 if (procCmdlineContent.empty()) {
97 return "";
98 }
99
100 size_t procNameStartPos = 0;
101 size_t procNameEndPos = procCmdlineContent.size();
102 for (size_t i = 0; i < procCmdlineContent.size(); i++) {
103 if (procCmdlineContent[i] == '/') {
104 procNameStartPos = i + 1;
105 } else if (procCmdlineContent[i] == '\0') {
106 procNameEndPos = i;
107 break;
108 }
109 }
110 return procCmdlineContent.substr(procNameStartPos, procNameEndPos - procNameStartPos);
111 }
112
GetLimitedSizeName(std::string name)113 std::string GetLimitedSizeName(std::string name)
114 {
115 const size_t nameStartPos = 0;
116 if (name.size() > MAX_NAME_SIZE) {
117 return name.substr(nameStartPos, MAX_NAME_SIZE);
118 }
119 return name;
120 }
121
IsProcessDebug(int32_t pid)122 bool IsProcessDebug(int32_t pid)
123 {
124 const int buffSize = 128;
125 char param[buffSize] = {0};
126 std::string filter = "hiviewdfx.freeze.filter." + GetProcessNameFromProcCmdline(pid);
127 GetParameter(filter.c_str(), "", param, buffSize - 1);
128 int32_t debugPid = atoi(param);
129 if (debugPid == pid) {
130 return true;
131 }
132 return false;
133 }
134
DelayBeforeExit(unsigned int leftTime)135 void DelayBeforeExit(unsigned int leftTime)
136 {
137 while (leftTime > 0) {
138 leftTime = sleep(leftTime);
139 }
140 }
141 } // end of HiviewDFX
142 } // end of OHOS