LLDB  mainline
NativeThreadFreeBSD.cpp
Go to the documentation of this file.
1 //===-- NativeThreadFreeBSD.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "NativeThreadFreeBSD.h"
11 
12 #include "NativeProcessFreeBSD.h"
13 
18 #include "lldb/Utility/State.h"
19 #include "llvm/Support/Errno.h"
20 
21 // clang-format off
22 #include <sys/types.h>
23 #include <sys/ptrace.h>
24 #include <sys/sysctl.h>
25 #include <sys/user.h>
26 // clang-format on
27 
28 #include <sstream>
29 #include <vector>
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 using namespace lldb_private::process_freebsd;
34 
35 NativeThreadFreeBSD::NativeThreadFreeBSD(NativeProcessFreeBSD &process,
36  lldb::tid_t tid)
37  : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
38  m_stop_info(),
39  m_reg_context_up(
40  NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
41  process.GetArchitecture(), *this)),
42  m_stop_description() {}
43 
46  if (!ret.Success())
47  return ret;
48  ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, GetID());
49  // we can get EINVAL if the architecture in question does not support
50  // hardware single-stepping -- that's fine, we have nothing to clear
51  // then
52  if (ret.GetError() == EINVAL)
53  ret.Clear();
54  if (ret.Success())
55  SetRunning();
56  return ret;
57 }
58 
61  if (!ret.Success())
62  return ret;
63  ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, GetID());
64  if (ret.Success())
65  SetStepping();
66  return ret;
67 }
68 
71  if (ret.Success())
72  SetStopped();
73  return ret;
74 }
75 
77  const siginfo_t *info) {
79  LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);
80 
81  SetStopped();
82 
84  m_stop_info.details.signal.signo = signo;
85 
86  m_stop_description.clear();
87  if (info) {
88  switch (signo) {
89  case SIGSEGV:
90  case SIGBUS:
91  case SIGFPE:
92  case SIGILL:
93  const auto reason = GetCrashReason(*info);
95  break;
96  }
97  }
98 }
99 
101  SetStopped();
104 }
105 
107  SetStopped();
110 }
111 
113  SetStopped();
116 }
117 
119  lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
120 
121  std::ostringstream ostr;
122  ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
123  ostr << wp_index;
124 
125  ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
126 
127  SetStopped();
128  m_stop_description = ostr.str();
131 }
132 
134  lldb::tid_t child_tid) {
135  SetStopped();
136 
138  m_stop_info.details.fork.child_pid = child_pid;
139  m_stop_info.details.fork.child_tid = child_tid;
140 }
141 
143  lldb::tid_t child_tid) {
144  SetStopped();
145 
147  m_stop_info.details.fork.child_pid = child_pid;
148  m_stop_info.details.fork.child_tid = child_tid;
149 }
150 
152  SetStopped();
153 
155 }
156 
158  SetStopped();
159 
161  m_stop_info.details.signal.signo = 0;
162 }
163 
165  const StateType new_state = StateType::eStateStopped;
166  m_state = new_state;
167  m_stop_description.clear();
168 }
169 
173 }
174 
178 }
179 
182 
183  std::vector<struct kinfo_proc> kp;
184  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
185  static_cast<int>(GetProcess().GetID())};
186 
187  while (1) {
188  size_t len = kp.size() * sizeof(struct kinfo_proc);
189  void *ptr = len == 0 ? nullptr : kp.data();
190  int error = ::sysctl(mib, 4, ptr, &len, nullptr, 0);
191  if (ptr == nullptr || (error != 0 && errno == ENOMEM)) {
192  kp.resize(len / sizeof(struct kinfo_proc));
193  continue;
194  }
195  if (error != 0) {
196  len = 0;
197  LLDB_LOG(log, "tid = {0} in state {1} failed to get thread name: {2}",
198  GetID(), m_state, strerror(errno));
199  }
200  kp.resize(len / sizeof(struct kinfo_proc));
201  break;
202  }
203 
204  for (auto &procinfo : kp) {
205  if (procinfo.ki_tid == static_cast<lwpid_t>(GetID()))
206  return procinfo.ki_tdname;
207  }
208 
209  return "";
210 }
211 
213 
215  std::string &description) {
217  description.clear();
218 
219  switch (m_state) {
220  case eStateStopped:
221  case eStateCrashed:
222  case eStateExited:
223  case eStateSuspended:
224  case eStateUnloaded:
225  stop_info = m_stop_info;
226  description = m_stop_description;
227 
228  return true;
229 
230  case eStateInvalid:
231  case eStateConnected:
232  case eStateAttaching:
233  case eStateLaunching:
234  case eStateRunning:
235  case eStateStepping:
236  case eStateDetached:
237  LLDB_LOG(log, "tid = {0} in state {1} cannot answer stop reason", GetID(),
239  return false;
240  }
241  llvm_unreachable("unhandled StateType!");
242 }
243 
245  assert(m_reg_context_up);
246  return *m_reg_context_up;
247 }
248 
250  uint32_t watch_flags, bool hardware) {
251  assert(m_state == eStateStopped);
252  if (!hardware)
253  return Status("not implemented");
254  Status error = RemoveWatchpoint(addr);
255  if (error.Fail())
256  return error;
257  uint32_t wp_index =
258  GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
259  if (wp_index == LLDB_INVALID_INDEX32)
260  return Status("Setting hardware watchpoint failed.");
261  m_watchpoint_index_map.insert({addr, wp_index});
262  return Status();
263 }
264 
266  auto wp = m_watchpoint_index_map.find(addr);
267  if (wp == m_watchpoint_index_map.end())
268  return Status();
269  uint32_t wp_index = wp->second;
270  m_watchpoint_index_map.erase(wp);
271  if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
272  return Status();
273  return Status("Clearing hardware watchpoint failed.");
274 }
275 
277  size_t size) {
278  assert(m_state == eStateStopped);
280  if (error.Fail())
281  return error;
282 
283  uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);
284 
285  if (bp_index == LLDB_INVALID_INDEX32)
286  return Status("Setting hardware breakpoint failed.");
287 
288  m_hw_break_index_map.insert({addr, bp_index});
289  return Status();
290 }
291 
293  auto bp = m_hw_break_index_map.find(addr);
294  if (bp == m_hw_break_index_map.end())
295  return Status();
296 
297  uint32_t bp_index = bp->second;
298  if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
299  m_hw_break_index_map.erase(bp);
300  return Status();
301  }
302 
303  return Status("Clearing hardware breakpoint failed.");
304 }
305 
309  source.GetRegisterContext());
310  if (!s) {
313  }
314  return s;
315 }
lldb_private::process_freebsd::NativeThreadFreeBSD::SingleStep
Status SingleStep()
Definition: NativeThreadFreeBSD.cpp:59
POSIX_LOG_THREAD
#define POSIX_LOG_THREAD
Definition: ProcessPOSIXLog.h:17
lldb_private::process_freebsd::NativeThreadFreeBSD::CopyWatchpointsFrom
llvm::Error CopyWatchpointsFrom(NativeThreadFreeBSD &source)
Definition: NativeThreadFreeBSD.cpp:307
NativeThreadFreeBSD.h
lldb_private::NativeThreadProtocol
Definition: NativeThreadProtocol.h:20
lldb::eStopReasonVFork
@ eStopReasonVFork
Definition: lldb-enumerations.h:253
lldb_private::NativeRegisterContext::SetHardwareBreakpoint
virtual uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
Definition: NativeRegisterContext.cpp:250
lldb_private::process_freebsd::NativeThreadFreeBSD::SetHardwareBreakpoint
Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override
Definition: NativeThreadFreeBSD.cpp:276
lldb_private::process_freebsd::NativeProcessFreeBSD
Definition: NativeProcessFreeBSD.h:30
lldb::eStateAttaching
@ eStateAttaching
Process is currently trying to attach.
Definition: lldb-enumerations.h:78
lldb_private::process_freebsd::NativeThreadFreeBSD::GetState
lldb::StateType GetState() override
Definition: NativeThreadFreeBSD.cpp:212
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByFork
void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid)
Definition: NativeThreadFreeBSD.cpp:133
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByTrace
void SetStoppedByTrace()
Definition: NativeThreadFreeBSD.cpp:106
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByVForkDone
void SetStoppedByVForkDone()
Definition: NativeThreadFreeBSD.cpp:151
lldb_private::NativeThreadProtocol::GetProcess
NativeProcessProtocol & GetProcess()
Definition: NativeThreadProtocol.h:37
lldb_private::StateAsCString
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition: State.cpp:14
lldb_private::process_freebsd::NativeRegisterContextFreeBSD::CopyHardwareWatchpointsFrom
virtual llvm::Error CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source)=0
lldb_private::ThreadStopInfo::details
union lldb_private::ThreadStopInfo::@13 details
RegisterValue.h
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::process_freebsd::NativeThreadFreeBSD
Definition: NativeThreadFreeBSD.h:25
lldb::eStopReasonTrace
@ eStopReasonTrace
Definition: lldb-enumerations.h:242
lldb_private::process_freebsd::NativeThreadFreeBSD::m_stop_description
std::string m_stop_description
Definition: NativeThreadFreeBSD.h:76
lldb_private::process_freebsd::NativeThreadFreeBSD::SetRunning
void SetRunning()
Definition: NativeThreadFreeBSD.cpp:170
lldb::eStateExited
@ eStateExited
Process has exited and can't be examined.
Definition: lldb-enumerations.h:90
lldb_private::process_freebsd::NativeThreadFreeBSD::GetName
std::string GetName() override
Definition: NativeThreadFreeBSD.cpp:180
lldb::eStateStopped
@ eStateStopped
Process or thread is stopped and can be examined.
Definition: lldb-enumerations.h:84
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByExec
void SetStoppedByExec()
Definition: NativeThreadFreeBSD.cpp:112
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:288
lldb::eStateCrashed
@ eStateCrashed
Process or thread has crashed and can be examined.
Definition: lldb-enumerations.h:88
LLDBAssert.h
lldb_private::process_freebsd::NativeProcessFreeBSD::PtraceWrapper
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, int data=0, int *result=nullptr)
Definition: NativeProcessFreeBSD.cpp:381
NativeProcessFreeBSD.h
lldb_private::NativeRegisterContext::GetWatchpointHitAddress
virtual lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index)
Definition: NativeRegisterContext.cpp:310
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStopped
void SetStopped()
Definition: NativeThreadFreeBSD.cpp:164
lldb_private::process_freebsd::NativeThreadFreeBSD::RemoveHardwareBreakpoint
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override
Definition: NativeThreadFreeBSD.cpp:292
lldb_private::process_freebsd
Definition: NativeProcessFreeBSD.h:22
lldb_private::Status::GetError
ValueType GetError() const
Access the error value.
Definition: Status.cpp:175
lldb_private::process_freebsd::NativeThreadFreeBSD::Suspend
Status Suspend()
Definition: NativeThreadFreeBSD.cpp:69
lldb::eStopReasonWatchpoint
@ eStopReasonWatchpoint
Definition: lldb-enumerations.h:244
lldb::eStopReasonNone
@ eStopReasonNone
Definition: lldb-enumerations.h:241
lldb::eStateConnected
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
Definition: lldb-enumerations.h:76
SIGTRAP
#define SIGTRAP
Definition: windows/PosixApi.h:30
lldb::eStateLaunching
@ eStateLaunching
Process is in the process of launching.
Definition: lldb-enumerations.h:79
lldb_private::process_freebsd::NativeThreadFreeBSD::m_reg_context_up
std::unique_ptr< NativeRegisterContextFreeBSD > m_reg_context_up
Definition: NativeThreadFreeBSD.h:75
lldb_private::ThreadStopInfo::reason
lldb::StopReason reason
Definition: Debug.h:134
lldb_private::NativeProcessProtocol::GetID
lldb::pid_t GetID() const
Definition: NativeProcessProtocol.h:172
lldb_private::process_freebsd::NativeThreadFreeBSD::RemoveWatchpoint
Status RemoveWatchpoint(lldb::addr_t addr) override
Definition: NativeThreadFreeBSD.cpp:265
ProcessPOSIXLog.h
lldb::eStateDetached
@ eStateDetached
Process has been detached and can't be examined.
Definition: lldb-enumerations.h:89
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::ThreadStopInfo::signal
struct lldb_private::ThreadStopInfo::@13::@14 signal
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedWithNoReason
void SetStoppedWithNoReason()
Definition: NativeThreadFreeBSD.cpp:157
lldb::eStateUnloaded
@ eStateUnloaded
Process is object is valid, but not currently loaded.
Definition: lldb-enumerations.h:75
lldb_private::ThreadStopInfo
Definition: Debug.h:133
lldb_private::process_freebsd::NativeThreadFreeBSD::Resume
Status Resume()
Definition: NativeThreadFreeBSD.cpp:44
lldb::eStateStepping
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
Definition: lldb-enumerations.h:86
lldbassert
#define lldbassert(x)
Definition: LLDBAssert.h:15
lldb::eStateSuspended
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
Definition: lldb-enumerations.h:91
lldb_private::process_freebsd::NativeThreadFreeBSD::SetWatchpoint
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override
Definition: NativeThreadFreeBSD.cpp:249
lldb::eStopReasonSignal
@ eStopReasonSignal
Definition: lldb-enumerations.h:245
GetCrashReasonString
std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info)
Definition: CrashReason.cpp:144
lldb::eStopReasonExec
@ eStopReasonExec
Program was re-exec'ed.
Definition: lldb-enumerations.h:247
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByBreakpoint
void SetStoppedByBreakpoint()
Definition: NativeThreadFreeBSD.cpp:100
lldb_private::Status
Definition: Status.h:44
uint32_t
lldb::pid_t
uint64_t pid_t
Definition: lldb-types.h:85
lldb_private::NativeThreadProtocol::GetID
lldb::tid_t GetID() const
Definition: NativeThreadProtocol.h:35
lldb_private::process_freebsd::NativeThreadFreeBSD::GetStopReason
bool GetStopReason(ThreadStopInfo &stop_info, std::string &description) override
Definition: NativeThreadFreeBSD.cpp:214
lldb_private::process_freebsd::NativeThreadFreeBSD::m_hw_break_index_map
WatchpointIndexMap m_hw_break_index_map
Definition: NativeThreadFreeBSD.h:79
lldb::eStopReasonBreakpoint
@ eStopReasonBreakpoint
Definition: lldb-enumerations.h:243
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:242
lldb_private::process_freebsd::NativeRegisterContextFreeBSD
Definition: NativeRegisterContextFreeBSD.h:21
lldb_private::ThreadStopInfo::fork
struct lldb_private::ThreadStopInfo::@13::@16 fork
NativeRegisterContextFreeBSD.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
lldb_private::process_freebsd::NativeThreadFreeBSD::GetRegisterContext
NativeRegisterContextFreeBSD & GetRegisterContext() override
Definition: NativeThreadFreeBSD.cpp:244
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByWatchpoint
void SetStoppedByWatchpoint(uint32_t wp_index)
Definition: NativeThreadFreeBSD.cpp:118
lldb::eStateInvalid
@ eStateInvalid
Definition: lldb-enumerations.h:74
lldb_private::Status::Clear
void Clear()
Clear the object state.
Definition: Status.cpp:168
State.h
LLDB_INVALID_INDEX32
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:87
lldb::StateType
StateType
Process and Thread States.
Definition: lldb-enumerations.h:73
lldb_private::Log
Definition: Log.h:49
lldb_private::ProcessPOSIXLog::GetLogIfAllCategoriesSet
static Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: ProcessPOSIXLog.h:33
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedBySignal
void SetStoppedBySignal(uint32_t signo, const siginfo_t *info=nullptr)
Definition: NativeThreadFreeBSD.cpp:76
lldb_private::NativeRegisterContext::SetHardwareWatchpoint
virtual uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags)
Definition: NativeRegisterContext.cpp:271
lldb::eStopReasonVForkDone
@ eStopReasonVForkDone
Definition: lldb-enumerations.h:254
lldb
Definition: SBAddress.h:15
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStoppedByVFork
void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid)
Definition: NativeThreadFreeBSD.cpp:142
lldb::eStateRunning
@ eStateRunning
Process or thread is running and can't be examined.
Definition: lldb-enumerations.h:85
lldb::eStopReasonFork
@ eStopReasonFork
Definition: lldb-enumerations.h:252
lldb_private::process_freebsd::NativeThreadFreeBSD::m_state
lldb::StateType m_state
Definition: NativeThreadFreeBSD.h:73
lldb_private::process_freebsd::NativeThreadFreeBSD::m_stop_info
ThreadStopInfo m_stop_info
Definition: NativeThreadFreeBSD.h:74
lldb_private::process_freebsd::NativeThreadFreeBSD::SetStepping
void SetStepping()
Definition: NativeThreadFreeBSD.cpp:175
lldb_private::process_freebsd::NativeThreadFreeBSD::m_watchpoint_index_map
WatchpointIndexMap m_watchpoint_index_map
Definition: NativeThreadFreeBSD.h:78
lldb_private::NativeRegisterContext::GetWatchpointAddress
virtual lldb::addr_t GetWatchpointAddress(uint32_t wp_index)
Definition: NativeRegisterContext.cpp:306
lldb::tid_t
uint64_t tid_t
Definition: lldb-types.h:86
CrashReason.h
GetCrashReason
CrashReason GetCrashReason(const siginfo_t &info)
Definition: CrashReason.cpp:341