• 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_thread.h"
17 
18 #include <cerrno>
19 #include <chrono>
20 #include <climits>
21 #include <cstring>
22 #include <securec.h>
23 #include <sstream>
24 #include <sys/wait.h>
25 #include <unistd.h>
26 
27 #include "dfx_define.h"
28 #if defined(__x86_64__)
29 #include "dfx_frame_format.h"
30 #else
31 #include "dfx_frame_formatter.h"
32 #endif
33 #include "dfx_log.h"
34 #include "dfx_ptrace.h"
35 #include "dfx_util.h"
36 #include "procinfo.h"
37 
38 namespace OHOS {
39 namespace HiviewDFX {
Create(pid_t pid,pid_t tid,pid_t nsTid)40 std::shared_ptr<DfxThread> DfxThread::Create(pid_t pid, pid_t tid, pid_t nsTid)
41 {
42     auto thread = std::make_shared<DfxThread>(pid, tid, nsTid);
43     return thread;
44 }
45 
DfxThread(pid_t pid,pid_t tid,pid_t nsTid)46 DfxThread::DfxThread(pid_t pid, pid_t tid, pid_t nsTid) : regs_(nullptr)
47 {
48     InitThreadInfo(pid, tid, nsTid);
49 }
50 
InitThreadInfo(pid_t pid,pid_t tid,pid_t nsTid)51 void DfxThread::InitThreadInfo(pid_t pid, pid_t tid, pid_t nsTid)
52 {
53     threadInfo_.pid = pid;
54     threadInfo_.tid = tid;
55     threadInfo_.nsTid = nsTid;
56     ReadThreadName(threadInfo_.tid, threadInfo_.threadName);
57     threadStatus = ThreadStatus::THREAD_STATUS_INIT;
58 }
59 
~DfxThread()60 DfxThread::~DfxThread()
61 {
62     threadStatus = ThreadStatus::THREAD_STATUS_INVALID;
63 }
64 
GetThreadRegs() const65 std::shared_ptr<DfxRegs> DfxThread::GetThreadRegs() const
66 {
67     return regs_;
68 }
69 
SetThreadRegs(const std::shared_ptr<DfxRegs> & regs)70 void DfxThread::SetThreadRegs(const std::shared_ptr<DfxRegs> &regs)
71 {
72     regs_ = regs;
73 }
74 
AddFrame(DfxFrame & frame)75 void DfxThread::AddFrame(DfxFrame& frame)
76 {
77     frames_.emplace_back(frame);
78 }
79 
GetFrames() const80 const std::vector<DfxFrame>& DfxThread::GetFrames() const
81 {
82     return frames_;
83 }
84 
ToString() const85 std::string DfxThread::ToString() const
86 {
87     if (frames_.size() == 0) {
88         return "No frame info";
89     }
90 
91     std::stringstream ss;
92     ss << "Thread name:" << threadInfo_.threadName << "" << std::endl;
93     for (size_t i = 0; i < frames_.size(); i++) {
94 #if defined(__x86_64__)
95         ss << DfxFrameFormat::GetFrameStr(frames_[i]);
96 #else
97         ss << DfxFrameFormatter::GetFrameStr(frames_[i]);
98 #endif
99     }
100     return ss.str();
101 }
102 
Detach()103 void DfxThread::Detach()
104 {
105     if (threadStatus == ThreadStatus::THREAD_STATUS_ATTACHED) {
106         DfxPtrace::Detach(threadInfo_.nsTid);
107         threadStatus = ThreadStatus::THREAD_STATUS_INIT;
108     }
109 }
110 
Attach()111 bool DfxThread::Attach()
112 {
113     if (threadStatus == ThreadStatus::THREAD_STATUS_ATTACHED) {
114         return true;
115     }
116 
117     if (!DfxPtrace::Attach(threadInfo_.nsTid)) {
118         return false;
119     }
120 
121     threadStatus = ThreadStatus::THREAD_STATUS_ATTACHED;
122     return true;
123 }
124 
InitFaultStack(bool needParseStack)125 void DfxThread::InitFaultStack(bool needParseStack)
126 {
127     if (faultStack_ != nullptr) {
128         return;
129     }
130     faultStack_ = std::make_shared<FaultStack>(threadInfo_.nsTid);
131     faultStack_->CollectStackInfo(frames_, needParseStack);
132 }
133 
134 
SetFrames(const std::vector<DfxFrame> & frames)135 void DfxThread::SetFrames(const std::vector<DfxFrame>& frames)
136 {
137     frames_ = frames;
138 }
139 
GetFaultStack() const140 std::shared_ptr<FaultStack> DfxThread::GetFaultStack() const
141 {
142     return faultStack_;
143 }
144 } // namespace HiviewDFX
145 } // nampespace OHOS
146