• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_process.h"
17 
18 #include <climits>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <dirent.h>
23 #include <securec.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <vector>
27 #include "dfx_config.h"
28 #include "dfx_define.h"
29 #include "dfx_logger.h"
30 #include "dfx_ring_buffer_wrapper.h"
31 #include "dfx_signal.h"
32 #include "dfx_util.h"
33 #include "procinfo.h"
34 
35 namespace OHOS {
36 namespace HiviewDFX {
Create(pid_t pid,pid_t nsPid)37 std::shared_ptr<DfxProcess> DfxProcess::Create(pid_t pid, pid_t nsPid)
38 {
39     auto process = std::make_shared<DfxProcess>(pid, nsPid);
40     return process;
41 }
42 
DfxProcess(pid_t pid,pid_t nsPid)43 DfxProcess::DfxProcess(pid_t pid, pid_t nsPid)
44 {
45     InitProcessInfo(pid, nsPid);
46 }
47 
InitProcessInfo(pid_t pid,pid_t nsPid)48 void DfxProcess::InitProcessInfo(pid_t pid, pid_t nsPid)
49 {
50     processInfo_.pid = pid;
51     processInfo_.nsPid = nsPid;
52     ReadProcessName(processInfo_.pid, processInfo_.processName);
53 }
54 
InitOtherThreads(bool attach)55 bool DfxProcess::InitOtherThreads(bool attach)
56 {
57     std::vector<int> tids;
58     std::vector<int> nstids;
59     if (!GetTidsByPid(processInfo_.pid, tids, nstids)) {
60         return false;
61     }
62 
63     for (size_t i = 0; i < nstids.size(); ++i) {
64         if ((recycleTid_ > 0) && (nstids[i] == static_cast<int>(recycleTid_))) {
65             DFXLOG_DEBUG("skip recycle thread:%d.", nstids[i]);
66             continue;
67         }
68 
69         if ((keyThread_ != nullptr) && nstids[i] == keyThread_->threadInfo_.nsTid) {
70             DFXLOG_DEBUG("skip key thread:%d.", nstids[i]);
71             continue;
72         }
73 
74         auto thread = DfxThread::Create(processInfo_.pid, tids[i], nstids[i]);
75         if (attach) {
76             thread->Attach();
77         }
78         otherThreads_.push_back(thread);
79     }
80     return true;
81 }
82 
ChangeTid(pid_t tid,bool ns)83 pid_t DfxProcess::ChangeTid(pid_t tid, bool ns)
84 {
85     if (processInfo_.pid == processInfo_.nsPid) {
86         return tid;
87     }
88 
89     if (kvThreads_.empty()) {
90         std::vector<int> tids;
91         std::vector<int> nstids;
92         if (!GetTidsByPid(processInfo_.pid, tids, nstids)) {
93             return tid;
94         }
95         for (size_t i = 0; i < nstids.size(); ++i) {
96             kvThreads_[nstids[i]] = tids[i];
97         }
98     }
99 
100     for (auto iter = kvThreads_.begin(); iter != kvThreads_.end(); iter++) {
101         if (ns && (iter->first == tid)) {
102             return iter->second;
103         }
104         if (!ns && (iter->second == tid)) {
105             return iter->first;
106         }
107     }
108     return tid;
109 }
110 
GetOtherThreads() const111 std::vector<std::shared_ptr<DfxThread>> DfxProcess::GetOtherThreads() const
112 {
113     return otherThreads_;
114 }
115 
ClearOtherThreads()116 void DfxProcess::ClearOtherThreads()
117 {
118     otherThreads_.clear();
119 }
120 
Attach(bool hasKey)121 void DfxProcess::Attach(bool hasKey)
122 {
123     if (hasKey && keyThread_) {
124         keyThread_->Attach();
125     }
126 
127     if (otherThreads_.empty()) {
128         return;
129     }
130     for (auto thread : otherThreads_) {
131         thread->Attach();
132     }
133 }
134 
Detach()135 void DfxProcess::Detach()
136 {
137     if (otherThreads_.empty()) {
138         return;
139     }
140 
141     for (auto thread : otherThreads_) {
142         thread->Detach();
143     }
144 }
145 
SetFatalMessage(const std::string & msg)146 void DfxProcess::SetFatalMessage(const std::string &msg)
147 {
148     fatalMsg_ = msg;
149 }
150 
GetFatalMessage() const151 std::string DfxProcess::GetFatalMessage() const
152 {
153     return fatalMsg_;
154 }
155 
SetMaps(std::shared_ptr<DfxElfMaps> maps)156 void DfxProcess::SetMaps(std::shared_ptr<DfxElfMaps> maps)
157 {
158     maps_ = maps;
159 }
160 
InitProcessMaps()161 void DfxProcess::InitProcessMaps()
162 {
163     if (maps_ == nullptr) {
164         if (processInfo_.pid <= 0) {
165             return;
166         }
167         maps_ = DfxElfMaps::Create(processInfo_.pid);
168     }
169 }
170 
GetMaps() const171 std::shared_ptr<DfxElfMaps> DfxProcess::GetMaps() const
172 {
173     return maps_;
174 }
175 } // namespace HiviewDFX
176 } // namespace OHOS
177