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