1 /*
2 * Copyright (c) 2022-2023 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_cutil.h"
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <stdio.h>
21 #include <syscall.h>
22 #include <unistd.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #include <securec.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include "dfx_define.h"
29
ReadStringFromFile(const char * path,char * dst,size_t dstSz)30 static bool ReadStringFromFile(const char* path, char* dst, size_t dstSz)
31 {
32 if ((dst == NULL) || (path == NULL) || (dstSz == 0)) {
33 return false;
34 }
35 int fd = OHOS_TEMP_FAILURE_RETRY(open(path, O_RDONLY));
36 if (fd < 0) {
37 return false;
38 }
39
40 char name[NAME_BUF_LEN] = {0};
41 ssize_t nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, name, NAME_BUF_LEN - 1));
42 if (nRead <= 0) {
43 syscall(SYS_close, fd);
44 return false;
45 }
46
47 size_t i = 0;
48 for (; i < dstSz - 1 && name[i] != '\n' && name[i] != '\0'; i++) {
49 dst[i] = name[i];
50 }
51 dst[i] = '\0';
52
53 syscall(SYS_close, fd);
54 return true;
55 }
56
GetThreadName(char * buffer,size_t bufferSz)57 bool GetThreadName(char* buffer, size_t bufferSz)
58 {
59 return ReadStringFromFile(PROC_SELF_COMM_PATH, buffer, bufferSz);
60 }
61
GetThreadNameByTid(int32_t tid,char * buffer,size_t bufferSz)62 bool GetThreadNameByTid(int32_t tid, char* buffer, size_t bufferSz)
63 {
64 char threadNamePath[NAME_BUF_LEN] = { 0 };
65 if (snprintf_s(threadNamePath, sizeof(threadNamePath), sizeof(threadNamePath) - 1, "/proc/%d/comm", tid) <= 0) {
66 return false;
67 }
68 return ReadStringFromFile(threadNamePath, buffer, bufferSz);
69 }
70
GetProcessName(char * buffer,size_t bufferSz)71 bool GetProcessName(char* buffer, size_t bufferSz)
72 {
73 return ReadStringFromFile(PROC_SELF_CMDLINE_PATH, buffer, bufferSz);
74 }
75
GetRealPid(void)76 pid_t GetRealPid(void)
77 {
78 return syscall(SYS_getpid);
79 }
80
GetTimeMilliseconds(void)81 uint64_t GetTimeMilliseconds(void)
82 {
83 struct timespec ts;
84 (void)clock_gettime(CLOCK_REALTIME, &ts);
85 return ((uint64_t)ts.tv_sec * NUMBER_ONE_THOUSAND) + // 1000 : second to millisecond convert ratio
86 (((uint64_t)ts.tv_nsec) / NUMBER_ONE_MILLION); // 1000000 : nanosecond to millisecond convert ratio
87 }
88
GetAbsTimeMilliSecondsCInterce(void)89 uint64_t GetAbsTimeMilliSecondsCInterce(void)
90 {
91 struct timespec ts;
92 (void)clock_gettime(CLOCK_MONOTONIC, &ts);
93 return ((uint64_t)(ts.tv_sec) * NUMBER_ONE_THOUSAND) +
94 ((uint64_t)(ts.tv_nsec) / NUMBER_ONE_MILLION);
95 }
96
ParseSiValue(const siginfo_t * si,uint64_t * endTime,int * tid)97 void ParseSiValue(const siginfo_t* si, uint64_t* endTime, int* tid)
98 {
99 const int flagOffset = 63;
100 if (((uint64_t)si->si_value.sival_ptr & (1ULL << flagOffset)) != 0) {
101 *endTime = (uint64_t)si->si_value.sival_ptr & (~(1ULL << flagOffset));
102 *tid = 0;
103 } else {
104 *endTime = 0;
105 *tid = si->si_value.sival_int;
106 }
107 }
108