• 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 #include "dfx_frame_formatter.h"
29 #include "dfx_log.h"
30 #include "dfx_ptrace.h"
31 #include "dfx_util.h"
32 #include "procinfo.h"
33 #if defined(__aarch64__)
34 #include "printer.h"
35 #endif
36 namespace OHOS {
37 namespace HiviewDFX {
Create(pid_t pid,pid_t tid,pid_t nsTid)38 std::shared_ptr<DfxThread> DfxThread::Create(pid_t pid, pid_t tid, pid_t nsTid)
39 {
40     auto thread = std::make_shared<DfxThread>(pid, tid, nsTid);
41     return thread;
42 }
43 
DfxThread(pid_t pid,pid_t tid,pid_t nsTid)44 DfxThread::DfxThread(pid_t pid, pid_t tid, pid_t nsTid) : regs_(nullptr)
45 {
46     InitThreadInfo(pid, tid, nsTid);
47 }
48 
InitThreadInfo(pid_t pid,pid_t tid,pid_t nsTid)49 void DfxThread::InitThreadInfo(pid_t pid, pid_t tid, pid_t nsTid)
50 {
51     threadInfo_.pid = pid;
52     threadInfo_.tid = tid;
53     threadInfo_.nsTid = nsTid;
54     ReadThreadNameByPidAndTid(threadInfo_.pid, threadInfo_.tid, threadInfo_.threadName);
55     threadStatus = ThreadStatus::THREAD_STATUS_INIT;
56 }
57 
~DfxThread()58 DfxThread::~DfxThread()
59 {
60     threadStatus = ThreadStatus::THREAD_STATUS_INVALID;
61 }
62 
GetThreadRegs() const63 std::shared_ptr<DfxRegs> DfxThread::GetThreadRegs() const
64 {
65     return regs_;
66 }
67 
SetThreadRegs(const std::shared_ptr<DfxRegs> & regs)68 void DfxThread::SetThreadRegs(const std::shared_ptr<DfxRegs> &regs)
69 {
70     regs_ = regs;
71 }
72 
AddFrame(DfxFrame & frame)73 void DfxThread::AddFrame(DfxFrame& frame)
74 {
75     frames_.emplace_back(frame);
76 }
77 
GetFrames() const78 const std::vector<DfxFrame>& DfxThread::GetFrames() const
79 {
80     return frames_;
81 }
82 
ToString() const83 std::string DfxThread::ToString() const
84 {
85     if (frames_.size() == 0) {
86         return "No frame info";
87     }
88 
89     std::stringstream ss;
90     ss << "Thread name:" << threadInfo_.threadName << "" << std::endl;
91     bool needSkip = false;
92     bool isSubmitter = true;
93     for (const auto& frame : frames_) {
94         if (frame.index == 0) {
95             isSubmitter = !isSubmitter;
96         }
97         if (isSubmitter) {
98             ss << "========SubmitterStacktrace========" << std::endl;
99             isSubmitter = false;
100             needSkip = false;
101         }
102         if (needSkip) {
103             continue;
104         }
105         ss << DfxFrameFormatter::GetFrameStr(frame);
106 #if defined(__aarch64__)
107         if (Printer::IsLastValidFrame(frame)) {
108             needSkip = true;
109         }
110 #endif
111     }
112     return ss.str();
113 }
114 
Detach()115 void DfxThread::Detach()
116 {
117     if (threadStatus == ThreadStatus::THREAD_STATUS_ATTACHED) {
118         DfxPtrace::Detach(threadInfo_.nsTid);
119         threadStatus = ThreadStatus::THREAD_STATUS_INIT;
120     }
121 }
122 
Attach(int timeout)123 bool DfxThread::Attach(int timeout)
124 {
125     if (threadStatus == ThreadStatus::THREAD_STATUS_ATTACHED) {
126         return true;
127     }
128 
129     if (!DfxPtrace::Attach(threadInfo_.nsTid, timeout)) {
130         return false;
131     }
132 
133     threadStatus = ThreadStatus::THREAD_STATUS_ATTACHED;
134     return true;
135 }
136 
InitFaultStack(bool needParseStack)137 void DfxThread::InitFaultStack(bool needParseStack)
138 {
139     if (faultStack_ != nullptr) {
140         return;
141     }
142     faultStack_ = std::make_shared<FaultStack>(threadInfo_.nsTid);
143     faultStack_->CollectStackInfo(frames_, needParseStack);
144 }
145 
146 
SetFrames(const std::vector<DfxFrame> & frames)147 void DfxThread::SetFrames(const std::vector<DfxFrame>& frames)
148 {
149     frames_ = frames;
150 }
151 
GetFaultStack() const152 std::shared_ptr<FaultStack> DfxThread::GetFaultStack() const
153 {
154     return faultStack_;
155 }
156 } // namespace HiviewDFX
157 } // nampespace OHOS
158