• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "collect_device_client.h"
16 
17 #include <cstring>
18 #include <iostream>
19 #include <memory>
20 #include <vector>
21 
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #include "hiview_logger.h"
28 #include "securec.h"
29 
30 #define UNIFIED_COLLECTION_DEVICE  "/dev/ucollection"
31 namespace OHOS {
32 namespace HiviewDFX {
33 DEFINE_LOG_TAG("UDeviceCli");
34 namespace {
35     constexpr int PID_ALL = 0;
36     constexpr unsigned int PROCESS_ONLY_ONE_COUNT = 1;
37     constexpr unsigned int ADD_COUNT = 30;
38 }
39 
CollectDeviceClient()40 CollectDeviceClient::CollectDeviceClient(): fd_(-1)
41 {}
42 
~CollectDeviceClient()43 CollectDeviceClient::~CollectDeviceClient()
44 {
45     if (fd_ >= 0) {
46         fdsan_close_with_tag(fd_, logLabelDomain);
47     }
48 }
49 
GetDeviceFd(bool readOnly)50 int CollectDeviceClient::GetDeviceFd(bool readOnly)
51 {
52     int f = 0;
53     if (readOnly) {
54         f = open(UNIFIED_COLLECTION_DEVICE, O_RDONLY);
55     } else {
56         f = open(UNIFIED_COLLECTION_DEVICE, O_WRONLY);
57     }
58 
59     if (f < 0) {
60         HIVIEW_LOGE("Cannot open file=%{public}s, readOnly=%{public}d", UNIFIED_COLLECTION_DEVICE, readOnly);
61         return -1;
62     }
63     HIVIEW_LOGD("open ucollection device readOnly=%{public}d successful", readOnly);
64     return f;
65 }
66 
Open()67 int CollectDeviceClient::Open()
68 {
69     fd_ = GetDeviceFd(true);
70     if (fd_ < 0) {
71         return -1;
72     }
73     fdsan_exchange_owner_tag(fd_, 0, logLabelDomain);
74     return 0;
75 }
76 
GetProcessCount()77 unsigned int CollectDeviceClient::GetProcessCount()
78 {
79     HIVIEW_LOGD("send IOCTRL_COLLECT_PROC_COUNT");
80     unsigned int processCount = 0;
81     int ret = ioctl(fd_, IOCTRL_COLLECT_PROC_COUNT, &processCount);
82     if (ret < 0) {
83         HIVIEW_LOGE("ioctl IOCTRL_COLLECT_PROC_COUNT, ret=%{public}d", ret);
84         return 0;
85     }
86     return processCount;
87 }
88 
FetchProcessCpuData()89 std::shared_ptr<ProcessCpuData> CollectDeviceClient::FetchProcessCpuData()
90 {
91     unsigned int processCount = GetProcessCount();
92     HIVIEW_LOGD("send IOCTRL_COLLECT_ALL_PROC_CPU");
93     std::shared_ptr<ProcessCpuData> data = std::make_shared<ProcessCpuData>(IOCTRL_COLLECT_ALL_PROC_CPU, PID_ALL,
94         processCount + ADD_COUNT);
95     int ret = ioctl(fd_, IOCTRL_COLLECT_ALL_PROC_CPU, data->entry_);
96     if (ret < 0) {
97         HIVIEW_LOGE("ioctl IOCTRL_COLLECT_ALL_PROC_CPU ret=%{public}d", ret);
98         return data;
99     }
100     return data;
101 }
102 
FetchProcessCpuData(int pid)103 std::shared_ptr<ProcessCpuData> CollectDeviceClient::FetchProcessCpuData(int pid)
104 {
105     HIVIEW_LOGD("send IOCTRL_COLLECT_THE_PROC_CPU");
106     std::shared_ptr<ProcessCpuData> data = std::make_shared<ProcessCpuData>(IOCTRL_COLLECT_THE_PROC_CPU, pid,
107         PROCESS_ONLY_ONE_COUNT);
108     int ret = ioctl(fd_, IOCTRL_COLLECT_THE_PROC_CPU, data->entry_);
109     if (ret < 0) {
110         HIVIEW_LOGE("ioctl IOCTRL_COLLECT_THE_PROC_CPU ret=%{public}d", ret);
111         return data;
112     }
113     return data;
114 }
115 
GetThreadCount(int pid)116 unsigned int CollectDeviceClient::GetThreadCount(int pid)
117 {
118     HIVIEW_LOGD("send IOCTRL_COLLECT_THREAD_COUNT");
119     struct ucollection_process_thread_count threadCount {pid, 0};
120     int ret = ioctl(fd_, IOCTRL_COLLECT_THREAD_COUNT, &threadCount);
121     if (ret < 0) {
122         HIVIEW_LOGE("ioctl IOCTRL_COLLECT_PROC_THREAD_COUNT ret=%{public}d", ret);
123         return 0;
124     }
125     return threadCount.thread_count;
126 }
127 
GetSelfThreadCount(int pid)128 unsigned int CollectDeviceClient::GetSelfThreadCount(int pid)
129 {
130     HIVIEW_LOGD("send IOCTRL_COLLECT_APP_THREAD_COUNT");
131     struct ucollection_process_thread_count threadCount {pid, 0};
132     int ret = ioctl(fd_, IOCTRL_COLLECT_APP_THREAD_COUNT, &threadCount);
133     if (ret < 0) {
134         HIVIEW_LOGE("ioctl IOCTRL_COLLECT_APP_THREAD_COUNT ret=%{public}d", ret);
135         return 0;
136     }
137     return threadCount.thread_count;
138 }
139 
FetchThreadCpuData(int pid)140 std::shared_ptr<ThreadCpuData> CollectDeviceClient::FetchThreadCpuData(int pid)
141 {
142     HIVIEW_LOGD("send IOCTRL_COLLECT_THE_THREAD");
143     unsigned int threadCount = GetThreadCount(pid);
144     if (threadCount <= 0) {
145         HIVIEW_LOGE("ioctl GetThreadCount error");
146         return nullptr;
147     }
148     auto data = std::make_shared<ThreadCpuData>(IOCTRL_COLLECT_THE_THREAD, pid, threadCount);
149     int ret = ioctl(fd_, IOCTRL_COLLECT_THE_THREAD, data->entry_);
150     if (ret < 0) {
151         HIVIEW_LOGE("ioctl FetchThreadData, ret=%{public}d", ret);
152         return data;
153     }
154     return data;
155 }
156 
FetchSelfThreadCpuData(int pid)157 std::shared_ptr<ThreadCpuData> CollectDeviceClient::FetchSelfThreadCpuData(int pid)
158 {
159     HIVIEW_LOGD("send IOCTRL_COLLECT_APP_THREAD, cmd=%{public}zu", IOCTRL_COLLECT_APP_THREAD);
160     unsigned int threadCount = GetSelfThreadCount(pid);
161     if (threadCount <= 0) {
162         HIVIEW_LOGE("ioctl GetSelfThreadCount error");
163         return nullptr;
164     }
165     auto data = std::make_shared<ThreadCpuData>(IOCTRL_COLLECT_APP_THREAD, pid, threadCount);
166     int ret = ioctl(fd_, IOCTRL_COLLECT_APP_THREAD, data->entry_);
167     if (ret < 0) {
168         HIVIEW_LOGE("ioctl FetchSelfThreadCpuData, ret=%{public}d", ret);
169         return data;
170     }
171     return data;
172 }
173 } // HiviewDFX
174 } // OHOS
175