LLDB  mainline
NativeThreadLinux.cpp
Go to the documentation of this file.
1 //===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===//
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 "NativeThreadLinux.h"
10 
11 #include <signal.h>
12 #include <sstream>
13 
14 #include "NativeProcessLinux.h"
16 #include "SingleStepCheck.h"
17 
19 #include "lldb/Host/linux/Ptrace.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/State.h"
24 #include "lldb/lldb-enumerations.h"
25 
26 #include "llvm/ADT/SmallString.h"
27 
29 
30 #include <sys/syscall.h>
31 // Try to define a macro to encapsulate the tgkill syscall
32 #define tgkill(pid, tid, sig) \
33  syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
34  sig)
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 using namespace lldb_private::process_linux;
39 
40 namespace {
41 void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
42  const char *const header) {
43  switch (stop_info.reason) {
44  case eStopReasonNone:
45  log.Printf("%s: %s no stop reason", __FUNCTION__, header);
46  return;
47  case eStopReasonTrace:
48  log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
49  stop_info.details.signal.signo);
50  return;
52  log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
53  header, stop_info.details.signal.signo);
54  return;
56  log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
57  header, stop_info.details.signal.signo);
58  return;
59  case eStopReasonSignal:
60  log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
61  stop_info.details.signal.signo);
62  return;
64  log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
65  stop_info.details.exception.type);
66  return;
67  case eStopReasonExec:
68  log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
69  stop_info.details.signal.signo);
70  return;
72  log.Printf("%s: %s plan complete", __FUNCTION__, header);
73  return;
75  log.Printf("%s: %s thread exiting", __FUNCTION__, header);
76  return;
78  log.Printf("%s: %s instrumentation", __FUNCTION__, header);
79  return;
80  default:
81  log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
82  static_cast<uint32_t>(stop_info.reason));
83  }
84 }
85 }
86 
87 NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
88  lldb::tid_t tid)
89  : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
90  m_stop_info(),
91  m_reg_context_up(
92  NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
93  process.GetArchitecture(), *this)),
94  m_stop_description() {}
95 
97  NativeProcessLinux &process = GetProcess();
98 
99  auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm");
100  if (!BufferOrError)
101  return "";
102  return BufferOrError.get()->getBuffer().rtrim('\n');
103 }
104 
106 
108  std::string &description) {
110 
111  description.clear();
112 
113  switch (m_state) {
114  case eStateStopped:
115  case eStateCrashed:
116  case eStateExited:
117  case eStateSuspended:
118  case eStateUnloaded:
119  if (log)
120  LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
121  stop_info = m_stop_info;
122  description = m_stop_description;
123  if (log)
124  LogThreadStopInfo(*log, stop_info, "returned stop_info:");
125 
126  return true;
127 
128  case eStateInvalid:
129  case eStateConnected:
130  case eStateAttaching:
131  case eStateLaunching:
132  case eStateRunning:
133  case eStateStepping:
134  case eStateDetached:
135  if (log) {
136  log->Printf("NativeThreadLinux::%s tid %" PRIu64
137  " in state %s cannot answer stop reason",
138  __FUNCTION__, GetID(), StateAsCString(m_state));
139  }
140  return false;
141  }
142  llvm_unreachable("unhandled StateType!");
143 }
144 
146  uint32_t watch_flags, bool hardware) {
147  if (!hardware)
148  return Status("not implemented");
149  if (m_state == eStateLaunching)
150  return Status();
151  Status error = RemoveWatchpoint(addr);
152  if (error.Fail())
153  return error;
154  uint32_t wp_index =
155  m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
156  if (wp_index == LLDB_INVALID_INDEX32)
157  return Status("Setting hardware watchpoint failed.");
158  m_watchpoint_index_map.insert({addr, wp_index});
159  return Status();
160 }
161 
163  auto wp = m_watchpoint_index_map.find(addr);
164  if (wp == m_watchpoint_index_map.end())
165  return Status();
166  uint32_t wp_index = wp->second;
167  m_watchpoint_index_map.erase(wp);
168  if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
169  return Status();
170  return Status("Clearing hardware watchpoint failed.");
171 }
172 
174  size_t size) {
175  if (m_state == eStateLaunching)
176  return Status();
177 
178  Status error = RemoveHardwareBreakpoint(addr);
179  if (error.Fail())
180  return error;
181 
182  uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
183 
184  if (bp_index == LLDB_INVALID_INDEX32)
185  return Status("Setting hardware breakpoint failed.");
186 
187  m_hw_break_index_map.insert({addr, bp_index});
188  return Status();
189 }
190 
192  auto bp = m_hw_break_index_map.find(addr);
193  if (bp == m_hw_break_index_map.end())
194  return Status();
195 
196  uint32_t bp_index = bp->second;
197  if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
198  m_hw_break_index_map.erase(bp);
199  return Status();
200  }
201 
202  return Status("Clearing hardware breakpoint failed.");
203 }
204 
205 Status NativeThreadLinux::Resume(uint32_t signo) {
206  const StateType new_state = StateType::eStateRunning;
207  MaybeLogStateChange(new_state);
208  m_state = new_state;
209 
210  m_stop_info.reason = StopReason::eStopReasonNone;
211  m_stop_description.clear();
212 
213  // If watchpoints have been set, but none on this thread, then this is a new
214  // thread. So set all existing watchpoints.
215  if (m_watchpoint_index_map.empty()) {
216  NativeProcessLinux &process = GetProcess();
217 
218  const auto &watchpoint_map = process.GetWatchpointMap();
219  m_reg_context_up->ClearAllHardwareWatchpoints();
220  for (const auto &pair : watchpoint_map) {
221  const auto &wp = pair.second;
222  SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
223  }
224  }
225 
226  // Set all active hardware breakpoint on all threads.
227  if (m_hw_break_index_map.empty()) {
228  NativeProcessLinux &process = GetProcess();
229 
230  const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
231  m_reg_context_up->ClearAllHardwareBreakpoints();
232  for (const auto &pair : hw_breakpoint_map) {
233  const auto &bp = pair.second;
234  SetHardwareBreakpoint(bp.m_addr, bp.m_size);
235  }
236  }
237 
238  intptr_t data = 0;
239 
240  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
241  data = signo;
242 
243  return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
244  reinterpret_cast<void *>(data));
245 }
246 
247 Status NativeThreadLinux::SingleStep(uint32_t signo) {
248  const StateType new_state = StateType::eStateStepping;
249  MaybeLogStateChange(new_state);
250  m_state = new_state;
251  m_stop_info.reason = StopReason::eStopReasonNone;
252 
253  if(!m_step_workaround) {
254  // If we already hava a workaround inplace, don't reset it. Otherwise, the
255  // destructor of the existing instance will run after the new instance has
256  // fetched the cpu mask, and the thread will end up with the wrong mask.
257  m_step_workaround = SingleStepWorkaround::Get(m_tid);
258  }
259 
260  intptr_t data = 0;
261  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
262  data = signo;
263 
264  // If hardware single-stepping is not supported, we just do a continue. The
265  // breakpoint on the next instruction has been setup in
266  // NativeProcessLinux::Resume.
268  GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
269  : PTRACE_CONT,
270  m_tid, nullptr, reinterpret_cast<void *>(data));
271 }
272 
273 void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
274  const siginfo_t *info) {
276  if (log)
277  log->Printf("NativeThreadLinux::%s called with signal 0x%02" PRIx32,
278  __FUNCTION__, signo);
279 
280  SetStopped();
281 
283  m_stop_info.details.signal.signo = signo;
284 
285  m_stop_description.clear();
286  if (info) {
287  switch (signo) {
288  case SIGSEGV:
289  case SIGBUS:
290  case SIGFPE:
291  case SIGILL:
292  // In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit
293  // address.
294  const auto reason =
295  (info->si_signo == SIGBUS && info->si_code == SI_KERNEL)
297  : GetCrashReason(*info);
298  m_stop_description = GetCrashReasonString(reason, *info);
299  break;
300  }
301  }
302 }
303 
304 bool NativeThreadLinux::IsStopped(int *signo) {
305  if (!StateIsStoppedState(m_state, false))
306  return false;
307 
308  // If we are stopped by a signal, return the signo.
309  if (signo && m_state == StateType::eStateStopped &&
310  m_stop_info.reason == StopReason::eStopReasonSignal) {
311  *signo = m_stop_info.details.signal.signo;
312  }
313 
314  // Regardless, we are stopped.
315  return true;
316 }
317 
318 void NativeThreadLinux::SetStopped() {
319  if (m_state == StateType::eStateStepping)
320  m_step_workaround.reset();
321 
322  const StateType new_state = StateType::eStateStopped;
323  MaybeLogStateChange(new_state);
324  m_state = new_state;
325  m_stop_description.clear();
326 }
327 
328 void NativeThreadLinux::SetStoppedByExec() {
330  if (log)
331  log->Printf("NativeThreadLinux::%s()", __FUNCTION__);
332 
333  SetStopped();
334 
335  m_stop_info.reason = StopReason::eStopReasonExec;
336  m_stop_info.details.signal.signo = SIGSTOP;
337 }
338 
339 void NativeThreadLinux::SetStoppedByBreakpoint() {
340  SetStopped();
341 
343  m_stop_info.details.signal.signo = SIGTRAP;
344  m_stop_description.clear();
345 }
346 
347 void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
348  SetStopped();
349 
350  lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
351 
352  std::ostringstream ostr;
353  ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
354  ostr << wp_index;
355 
356  /*
357  * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
358  * example:
359  * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
360  * 'm', then
361  * watch exception is generated even when 'n' is read/written. To handle this
362  * case,
363  * find the base address of the load/store instruction and append it in the
364  * stop-info
365  * packet.
366  */
367  ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
368 
369  m_stop_description = ostr.str();
370 
372  m_stop_info.details.signal.signo = SIGTRAP;
373 }
374 
375 bool NativeThreadLinux::IsStoppedAtBreakpoint() {
376  return GetState() == StateType::eStateStopped &&
378 }
379 
380 bool NativeThreadLinux::IsStoppedAtWatchpoint() {
381  return GetState() == StateType::eStateStopped &&
383 }
384 
385 void NativeThreadLinux::SetStoppedByTrace() {
386  SetStopped();
387 
388  m_stop_info.reason = StopReason::eStopReasonTrace;
389  m_stop_info.details.signal.signo = SIGTRAP;
390 }
391 
392 void NativeThreadLinux::SetStoppedWithNoReason() {
393  SetStopped();
394 
395  m_stop_info.reason = StopReason::eStopReasonNone;
396  m_stop_info.details.signal.signo = 0;
397 }
398 
399 void NativeThreadLinux::SetExited() {
400  const StateType new_state = StateType::eStateExited;
401  MaybeLogStateChange(new_state);
402  m_state = new_state;
403 
405 }
406 
407 Status NativeThreadLinux::RequestStop() {
409 
410  NativeProcessLinux &process = GetProcess();
411 
412  lldb::pid_t pid = process.GetID();
413  lldb::tid_t tid = GetID();
414 
415  if (log)
416  log->Printf("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
417  ", tid: %" PRIu64 ")",
418  __FUNCTION__, pid, tid);
419 
420  Status err;
421  errno = 0;
422  if (::tgkill(pid, tid, SIGSTOP) != 0) {
423  err.SetErrorToErrno();
424  if (log)
425  log->Printf("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
426  ", SIGSTOP) failed: %s",
427  __FUNCTION__, pid, tid, err.AsCString());
428  }
429 
430  return err;
431 }
432 
433 void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
435  // If we're not logging, we're done.
436  if (!log)
437  return;
438 
439  // If this is a state change to the same state, we're done.
440  lldb::StateType old_state = m_state;
441  if (new_state == old_state)
442  return;
443 
444  LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
445  m_process.GetID(), GetID(), old_state, new_state);
446 }
447 
448 NativeProcessLinux &NativeThreadLinux::GetProcess() {
449  return static_cast<NativeProcessLinux &>(m_process);
450 }
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition: State.cpp:14
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
virtual const NativeWatchpointList::WatchpointMap & GetWatchpointMap() const
#define lldbassert(x)
Definition: LLDBAssert.h:15
Process is currently trying to attach.
#define LLDB_INVALID_SIGNAL_NUMBER
Definition: lldb-defines.h:95
CrashReason GetCrashReason(const siginfo_t &info)
virtual const HardwareBreakpointMap & GetHardwareBreakpointMap() const
Process or thread is stopped and can be examined.
#define LLDB_LOG(log,...)
Definition: Log.h:209
Process or thread has crashed and can be examined.
#define SIGSTOP
void SetErrorToErrno()
Set the current error to errno.
Definition: Status.cpp:223
Process has exited and can&#39;t be examined.
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:86
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
Definition: State.cpp:89
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
bool GetStopReason(ThreadStopInfo &stop_info, std::string &description) override
#define LIBLLDB_LOG_THREAD
Definition: Logging.h:16
Process is connected to remote debug services, but not launched or attached to anything yet...
Process has been detached and can&#39;t be examined.
#define tgkill(pid, tid, sig)
Process is in the process of launching.
uint64_t tid_t
Definition: lldb-types.h:86
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override
Manages communication with the inferior (debugee) process.
struct lldb_private::ThreadStopInfo::@11::@13 exception
Process or thread is in the process of stepping and can not be examined.
Process is object is valid, but not currently loaded.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file)
Definition: Support.cpp:14
static std::unique_ptr< SingleStepWorkaround > Get(::pid_t tid)
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
lldb::StopReason reason
Definition: Debug.h:134
uint64_t addr_t
Definition: lldb-types.h:83
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override
Definition: SBAddress.h:15
uint64_t pid_t
Definition: lldb-types.h:85
std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info)
#define SIGTRAP
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
Status RemoveWatchpoint(lldb::addr_t addr) override
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
struct lldb_private::ThreadStopInfo::@11::@12 signal
union lldb_private::ThreadStopInfo::@11 details
An error handling class.
Definition: Status.h:44
Process or thread is running and can&#39;t be examined.