• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 /* This files contains process dump common tool functions. */
17 
18 #include "dfx_util.h"
19 
20 #include <cctype>
21 #include <climits>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25 #include <ctime>
26 #include <fstream>
27 #include <iostream>
28 #include <securec.h>
29 #include <unistd.h>
30 #include "dfx_define.h"
31 #include "dfx_logger.h"
32 
33 namespace OHOS {
34 namespace HiviewDFX {
35 static const int ARGS_COUNT_ONE = 1;
36 static const int ARGS_COUNT_TWO = 2;
GetProcStatusByPath(const std::string & path,struct ProcInfo & procInfo)37 static int GetProcStatusByPath(const std::string& path, struct ProcInfo& procInfo)
38 {
39     char buf[STATUS_LINE_SIZE];
40     FILE *fp = fopen(path.c_str(), "r");
41     if (fp == nullptr) {
42         return -1;
43     }
44 
45     int p = 0, pp = 0, t = 0;
46     while (!feof(fp)) {
47         if (fgets(buf, STATUS_LINE_SIZE, fp) == nullptr) {
48             fclose(fp);
49             return -1;
50         }
51 
52         if (strncmp(buf, PID_STR_NAME, strlen(PID_STR_NAME)) == 0) {
53             // Pid:    1892
54             if (sscanf_s(buf, "%*[^0-9]%d", &p) != ARGS_COUNT_ONE) {
55                 DfxLogError("sscanf_s failed.");
56             }
57             procInfo.pid = p;
58             if (procInfo.pid == getpid()) {
59                 procInfo.ns = false;
60                 procInfo.tid = gettid();
61                 procInfo.ppid = getppid();
62                 break;
63             }
64             procInfo.ns = true;
65             continue;
66         }
67 
68         if (strncmp(buf, PPID_STR_NAME, strlen(PPID_STR_NAME)) == 0) {
69             // PPid:   240
70             if (sscanf_s(buf, "%*[^0-9]%d", &pp) != ARGS_COUNT_ONE) {
71                 DfxLogError("sscanf_s failed.");
72             }
73             procInfo.ppid = pp;
74             continue;
75         }
76 
77         // NSpid:  1892    1
78         if (strncmp(buf, NSPID_STR_NAME, strlen(NSPID_STR_NAME)) == 0) {
79             if (sscanf_s(buf, "%*[^0-9]%d%*[^0-9]%d", &p, &t) != ARGS_COUNT_TWO) {
80                 DfxLogError("sscanf_s failed.");
81             }
82             procInfo.tid = t;
83             break;
84         }
85     }
86     (void)fclose(fp);
87     return 0;
88 }
89 
GetRealTargetPid()90 int GetRealTargetPid()
91 {
92     ProcInfo procInfo;
93     (void)memset_s(&procInfo, sizeof(procInfo), 0, sizeof(struct ProcInfo));
94     if (GetProcStatus(procInfo) == -1) {
95         return -1;
96     }
97 
98     return procInfo.ppid;
99 }
100 
GetProcStatusByPid(int realPid,struct ProcInfo & procInfo)101 int GetProcStatusByPid(int realPid, struct ProcInfo& procInfo)
102 {
103     std::string path = "/proc/" + std::to_string(realPid) + "/status";
104     return GetProcStatusByPath(path, procInfo);
105 }
106 
GetProcStatus(struct ProcInfo & procInfo)107 int GetProcStatus(struct ProcInfo& procInfo)
108 {
109     return GetProcStatusByPath(PROC_SELF_STATUS_PATH, procInfo);
110 }
111 
ReadStringFromFile(const std::string & path,std::string & buf,size_t len)112 bool ReadStringFromFile(const std::string &path, std::string &buf, size_t len)
113 {
114     if (len <= 1) {
115         return false;
116     }
117 
118     char realPath[PATH_MAX] = {0};
119     if (!realpath(path.c_str(), realPath)) {
120         return false;
121     }
122 
123     std::ifstream file;
124     file.open(realPath);
125     if (!file.is_open()) {
126         return false;
127     }
128 
129     std::istreambuf_iterator<char> start(file), end;
130     std::string str(start, end);
131     buf = str.substr(0, len);
132     file.close();
133     return true;
134 }
135 
TrimAndDupStr(const std::string & source,std::string & str)136 bool TrimAndDupStr(const std::string &source, std::string &str)
137 {
138     if (source.empty()) {
139         return false;
140     }
141 
142     const char *begin = source.data();
143     const char *end = begin + source.size();
144     if (begin == end) {
145         DfxLogError("Source is empty");
146         return false;
147     }
148 
149     while ((begin < end) && isspace(*begin)) {
150         begin++;
151     }
152 
153     while ((begin < end) && isspace(*(end - 1))) {
154         end--;
155     }
156 
157     if (begin == end) {
158         return false;
159     }
160 
161     uint32_t maxStrLen = NAME_LEN;
162     uint32_t offset = static_cast<uint32_t>(end - begin);
163     if (maxStrLen > offset) {
164         maxStrLen = offset;
165     }
166 
167     str.assign(begin, maxStrLen);
168     return true;
169 }
170 
GetCurrentTimeStr(uint64_t current)171 std::string GetCurrentTimeStr(uint64_t current)
172 {
173     time_t now = time(nullptr);
174     uint64_t millsecond = 0;
175     const uint64_t ratio = 1000;
176     if (current > static_cast<uint64_t>(now)) {
177         millsecond = current % ratio;
178         now = static_cast<time_t>(current / ratio);
179     }
180 
181     auto tm = std::localtime(&now);
182     char seconds[128] = {0}; // 128 : time buffer size
183     if (tm == nullptr || strftime(seconds, sizeof(seconds) - 1, "%Y-%m-%d %H:%M:%S", tm) == 0) {
184         return "invalid timestamp\n";
185     }
186 
187     char millBuf[256] = {0}; // 256 : milliseconds buffer size
188     int ret = snprintf_s(millBuf, sizeof(millBuf), sizeof(millBuf) - 1,
189         "%s.%03u\n", seconds, millsecond);
190     if (ret <= 0) {
191         return "invalid timestamp\n";
192     }
193     return std::string(millBuf, strlen(millBuf));
194 }
195 
PrintFormat(char * buf,int size,const char * format,...)196 int PrintFormat(char *buf, int size, const char *format, ...)
197 {
198     int ret = -1;
199     va_list args;
200     va_start(args, format);
201     ret = vsnprintf_s(buf, size, size - 1, format, args);
202     va_end(args);
203     if (ret <= 0) {
204         DfxLogError("snprintf_s failed.");
205     }
206     return ret;
207 }
208 }   // namespace HiviewDFX
209 }   // namespace OHOS
210