LLDB mainline
NativeThreadLinux.cpp
Go to the documentation of this file.
1//===-- NativeThreadLinux.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 "NativeThreadLinux.h"
10
21#include "lldb/Utility/Log.h"
22#include "lldb/Utility/State.h"
24#include "llvm/ADT/SmallString.h"
25
26#include <csignal>
27#include <sstream>
28#include <sys/syscall.h>
29// Try to define a macro to encapsulate the tgkill syscall
30#define tgkill(pid, tid, sig) \
31 syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
32 sig)
33
34using namespace lldb;
35using namespace lldb_private;
36using namespace lldb_private::process_linux;
37
38namespace {
39void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
40 const char *const header) {
41 switch (stop_info.reason) {
42 case eStopReasonNone:
43 log.Printf("%s: %s no stop reason", __FUNCTION__, header);
44 return;
46 log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
47 stop_info.signo);
48 return;
50 log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
51 header, stop_info.signo);
52 return;
54 log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
55 header, stop_info.signo);
56 return;
58 log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
59 stop_info.signo);
60 return;
62 log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
63 stop_info.details.exception.type);
64 return;
65 case eStopReasonExec:
66 log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
67 stop_info.signo);
68 return;
70 log.Printf("%s: %s plan complete", __FUNCTION__, header);
71 return;
73 log.Printf("%s: %s thread exiting", __FUNCTION__, header);
74 return;
76 log.Printf("%s: %s instrumentation", __FUNCTION__, header);
77 return;
79 log.Printf("%s: %s processor trace", __FUNCTION__, header);
80 return;
82 log.Printf("%s: %s history boundary", __FUNCTION__, header);
83 return;
84 default:
85 log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
86 static_cast<uint32_t>(stop_info.reason));
87 }
88}
89}
90
92 lldb::tid_t tid)
95 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
96 process.GetArchitecture(), *this)) {}
97
99 NativeProcessLinux &process = GetProcess();
100
101 auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm");
102 if (!BufferOrError)
103 return "";
104 return std::string(BufferOrError.get()->getBuffer().rtrim('\n'));
105}
106
108
110 std::string &description) {
111 Log *log = GetLog(LLDBLog::Thread);
112
113 description.clear();
114
115 switch (m_state) {
116 case eStateStopped:
117 case eStateCrashed:
118 case eStateExited:
119 case eStateSuspended:
120 case eStateUnloaded:
121 if (log)
122 LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
123 stop_info = m_stop_info;
124 description = m_stop_description;
125 if (log)
126 LogThreadStopInfo(*log, stop_info, "returned stop_info:");
127
128 return true;
129
130 case eStateInvalid:
131 case eStateConnected:
132 case eStateAttaching:
133 case eStateLaunching:
134 case eStateRunning:
135 case eStateStepping:
136 case eStateDetached:
137 LLDB_LOGF(log,
138 "NativeThreadLinux::%s tid %" PRIu64
139 " in state %s cannot answer stop reason",
140 __FUNCTION__, GetID(), StateAsCString(m_state));
141 return false;
142 }
143 llvm_unreachable("unhandled StateType!");
144}
145
147 uint32_t watch_flags, bool hardware) {
148 if (!hardware)
149 return Status::FromErrorString("not implemented");
151 return Status();
153 if (error.Fail())
154 return error;
155 uint32_t wp_index =
156 m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
157 if (wp_index == LLDB_INVALID_INDEX32)
158 return Status::FromErrorString("Setting hardware watchpoint failed.");
159 m_watchpoint_index_map.insert({addr, wp_index});
160 return Status();
161}
162
164 auto wp = m_watchpoint_index_map.find(addr);
165 if (wp == m_watchpoint_index_map.end())
166 return Status();
167 uint32_t wp_index = wp->second;
168 m_watchpoint_index_map.erase(wp);
169 if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
170 return Status();
171 return Status::FromErrorString("Clearing hardware watchpoint failed.");
172}
173
175 size_t size) {
177 return Status();
178
180 if (error.Fail())
181 return error;
182
183 uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
184
185 if (bp_index == LLDB_INVALID_INDEX32)
186 return Status::FromErrorString("Setting hardware breakpoint failed.");
187
188 m_hw_break_index_map.insert({addr, bp_index});
189 return Status();
190}
191
193 auto bp = m_hw_break_index_map.find(addr);
194 if (bp == m_hw_break_index_map.end())
195 return Status();
196
197 uint32_t bp_index = bp->second;
198 if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
199 m_hw_break_index_map.erase(bp);
200 return Status();
201 }
202
203 return Status::FromErrorString("Clearing hardware breakpoint failed.");
204}
205
207 const StateType new_state = StateType::eStateRunning;
208 MaybeLogStateChange(new_state);
209 m_state = new_state;
210
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
248 const StateType new_state = StateType::eStateStepping;
249 MaybeLogStateChange(new_state);
250 m_state = new_state;
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.
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
274 const siginfo_t *info) {
275 Log *log = GetLog(LLDBLog::Thread);
276 LLDB_LOGF(log, "NativeThreadLinux::%s called with signal 0x%02" PRIx32,
277 __FUNCTION__, signo);
278
279 SetStopped();
280
282 m_stop_info.signo = signo;
283
284 m_stop_description.clear();
285 if (info) {
286 switch (signo) {
287 case SIGSEGV:
288 case SIGBUS:
289 case SIGFPE:
290 case SIGILL:
292#ifndef SEGV_MTESERR
293#define SEGV_MTESERR 9
294#endif
295 if (info->si_signo == SIGSEGV && info->si_code == SEGV_MTESERR)
297 reinterpret_cast<lldb::addr_t>(info->si_addr));
298 break;
299 }
300 }
301}
302
304 int32_t allocation_tag_type = 0;
305 switch (GetProcess().GetArchitecture().GetMachine()) {
306 // aarch64_32 deliberately not here because there's no 32 bit MTE
307 case llvm::Triple::aarch64:
308 case llvm::Triple::aarch64_be:
310 break;
311 default:
312 return;
313 }
314
315 auto details =
316 GetRegisterContext().GetMemoryTaggingDetails(allocation_tag_type);
317 if (!details) {
318 llvm::consumeError(details.takeError());
319 return;
320 }
321
322 // We assume that the stop description is currently:
323 // signal SIGSEGV: sync tag check fault (fault address=<addr>)
324 // Remove the closing )
325 m_stop_description.pop_back();
326
327 std::stringstream ss;
328 std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
329
330 ss << " logical tag=0x" << std::hex << manager->GetLogicalTag(fault_addr);
331
332 std::vector<uint8_t> allocation_tag_data;
333 // The fault address may not be granule aligned. ReadMemoryTags will granule
334 // align any range you give it, potentially making it larger.
335 // To prevent this set len to 1. This always results in a range that is at
336 // most 1 granule in size and includes fault_addr.
337 Status status = GetProcess().ReadMemoryTags(allocation_tag_type, fault_addr,
338 1, allocation_tag_data);
339
340 if (status.Success()) {
341 llvm::Expected<std::vector<lldb::addr_t>> allocation_tag =
342 manager->UnpackTagsData(allocation_tag_data, 1);
343 if (allocation_tag) {
344 ss << " allocation tag=0x" << std::hex << allocation_tag->front() << ")";
345 } else {
346 llvm::consumeError(allocation_tag.takeError());
347 ss << ")";
348 }
349 } else
350 ss << ")";
351
352 m_stop_description += ss.str();
353}
354
356 if (!StateIsStoppedState(m_state, false))
357 return false;
358
359 // If we are stopped by a signal, return the signo.
360 if (signo && m_state == StateType::eStateStopped &&
362 *signo = m_stop_info.signo;
363 }
364
365 // Regardless, we are stopped.
366 return true;
367}
368
371 m_step_workaround.reset();
372
373 // On every stop, clear any cached register data structures
375
376 const StateType new_state = StateType::eStateStopped;
377 MaybeLogStateChange(new_state);
378 m_state = new_state;
379 m_stop_description.clear();
380}
381
383 Log *log = GetLog(LLDBLog::Thread);
384 LLDB_LOGF(log, "NativeThreadLinux::%s()", __FUNCTION__);
385
386 SetStopped();
387
389 m_stop_info.signo = SIGSTOP;
390}
391
399
401 SetStopped();
402
403 lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
404
405 std::ostringstream ostr;
406 ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
407 ostr << wp_index;
408
409 /*
410 * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
411 * example:
412 * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
413 * 'm', then
414 * watch exception is generated even when 'n' is read/written. To handle this
415 * case,
416 * find the base address of the load/store instruction and append it in the
417 * stop-info
418 * packet.
419 */
420 ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
421
422 m_stop_description = ostr.str();
423
425 m_stop_info.signo = SIGTRAP;
426}
427
432
437
444
445void NativeThreadLinux::SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid) {
446 SetStopped();
447
448 m_stop_info.reason =
450 m_stop_info.signo = SIGTRAP;
451 m_stop_info.details.fork.child_pid = child_pid;
452 m_stop_info.details.fork.child_tid = child_pid;
453 m_stop_description = std::to_string(child_pid);
454 m_stop_description += " ";
455 m_stop_description += std::to_string(child_pid);
456}
457
464
471
473 llvm::StringRef description) {
474 SetStopped();
475
477 m_stop_info.signo = 0;
478 m_stop_description = description.str();
479}
480
482 const StateType new_state = StateType::eStateExited;
483 MaybeLogStateChange(new_state);
484 m_state = new_state;
485
487}
488
490 Log *log = GetLog(LLDBLog::Thread);
491
492 NativeProcessLinux &process = GetProcess();
493
494 lldb::pid_t pid = process.GetID();
495 lldb::tid_t tid = GetID();
496
497 LLDB_LOGF(log,
498 "NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
499 ", tid: %" PRIu64 ")",
500 __FUNCTION__, pid, tid);
501
502 Status err;
503 errno = 0;
504 if (::tgkill(pid, tid, SIGSTOP) != 0) {
505 err = Status::FromErrno();
506 LLDB_LOGF(log,
507 "NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
508 ", SIGSTOP) failed: %s",
509 __FUNCTION__, pid, tid, err.AsCString());
510 }
511
512 return err;
513}
514
516 Log *log = GetLog(LLDBLog::Thread);
517 // If we're not logging, we're done.
518 if (!log)
519 return;
520
521 // If this is a state change to the same state, we're done.
522 lldb::StateType old_state = m_state;
523 if (new_state == old_state)
524 return;
525
526 LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
527 m_process.GetID(), GetID(), old_state, new_state);
528}
529
533
535 return static_cast<const NativeProcessLinux &>(m_process);
536}
537
538llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
540 auto siginfo_buf =
541 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(sizeof(siginfo_t));
542 Status error =
543 GetProcess().GetSignalInfo(GetID(), siginfo_buf->getBufferStart());
544 if (!error.Success())
545 return error.ToError();
546 return std::move(siginfo_buf);
547}
static llvm::raw_ostream & error(Stream &strm)
std::string GetCrashReasonString(const siginfo_t &info)
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define SEGV_MTESERR
#define tgkill(pid, tid, sig)
#define SIGILL
#define SIGFPE
#define SIGSEGV
#define SIGBUS
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
Definition Log.cpp:177
virtual const HardwareBreakpointMap & GetHardwareBreakpointMap() const
virtual const NativeWatchpointList::WatchpointMap & GetWatchpointMap() const
NativeThreadProtocol(NativeProcessProtocol &process, lldb::tid_t tid)
An error handling class.
Definition Status.h:118
static Status FromErrno()
Set the current error to errno.
Definition Status.cpp:299
static Status FromErrorString(const char *str)
Definition Status.h:141
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
bool Success() const
Test for success condition.
Definition Status.cpp:303
Status GetSignalInfo(lldb::tid_t tid, void *siginfo) const
Writes a siginfo_t structure corresponding to the given thread ID to the memory region pointed to by ...
Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len, std::vector< uint8_t > &tags) override
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
}
virtual llvm::Expected< MemoryTaggingDetails > GetMemoryTaggingDetails(int32_t type)
Return architecture specific data needed to use memory tags, if they are supported.
NativeThreadLinux(NativeProcessLinux &process, lldb::tid_t tid)
void AnnotateSyncTagCheckFault(lldb::addr_t fault_addr)
Extend m_stop_description with logical and allocation tag values.
void MaybeLogStateChange(lldb::StateType new_state)
bool GetStopReason(ThreadStopInfo &stop_info, std::string &description) override
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > GetSiginfo() const override
void SetStoppedBySignal(uint32_t signo, const siginfo_t *info=nullptr)
Status RemoveWatchpoint(lldb::addr_t addr) override
std::unique_ptr< NativeRegisterContextLinux > m_reg_context_up
Status SingleStep(uint32_t signo)
Single steps the thread.
std::unique_ptr< SingleStepWorkaround > m_step_workaround
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override
bool IsStopped(int *signo)
Return true if the thread is stopped.
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override
Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override
void SetStoppedByProcessorTrace(llvm::StringRef description)
NativeRegisterContextLinux & GetRegisterContext() override
Status Resume(uint32_t signo)
Resumes the thread.
void SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid)
static std::unique_ptr< SingleStepWorkaround > Get(::pid_t tid)
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_INDEX32
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file)
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
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateLaunching
Process is in the process of launching.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
uint64_t pid_t
Definition lldb-types.h:84
uint64_t addr_t
Definition lldb-types.h:80
@ eStopReasonInstrumentation
@ eStopReasonPlanComplete
@ eStopReasonHistoryBoundary
@ eStopReasonBreakpoint
@ eStopReasonExec
Program was re-exec'ed.
@ eStopReasonVForkDone
@ eStopReasonProcessorTrace
@ eStopReasonThreadExiting
@ eStopReasonException
@ eStopReasonWatchpoint
uint64_t tid_t
Definition lldb-types.h:85
struct lldb_private::ThreadStopInfo::@116236113001137253323017204263037302160273237376::@034237007264067231263360140073224264215170222231 exception
lldb::StopReason reason
Definition Debug.h:132
union lldb_private::ThreadStopInfo::@116236113001137253323017204263037302160273237376 details
#define SIGSTOP
#define SIGTRAP