27#include "llvm/ADT/SmallString.h"
32#include <sys/syscall.h>
34#define tgkill(pid, tid, sig) \
35 syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
44 const char *
const header) {
45 switch (stop_info.
reason) {
47 log.
Printf(
"%s: %s no stop reason", __FUNCTION__, header);
50 log.
Printf(
"%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
54 log.
Printf(
"%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
55 header, stop_info.
signo);
58 log.
Printf(
"%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
59 header, stop_info.
signo);
62 log.
Printf(
"%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
66 log.
Printf(
"%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
70 log.
Printf(
"%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
74 log.
Printf(
"%s: %s plan complete", __FUNCTION__, header);
77 log.
Printf(
"%s: %s thread exiting", __FUNCTION__, header);
80 log.
Printf(
"%s: %s instrumentation", __FUNCTION__, header);
83 log.
Printf(
"%s: %s processor trace", __FUNCTION__, header);
86 log.
Printf(
"%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
87 static_cast<uint32_t
>(stop_info.
reason));
98 process.GetArchitecture(), *this)),
99 m_stop_description() {}
107 return std::string(BufferOrError.get()->getBuffer().rtrim(
'\n'));
113 std::string &description) {
125 LogThreadStopInfo(*log,
m_stop_info,
"m_stop_info in thread:");
129 LogThreadStopInfo(*log, stop_info,
"returned stop_info:");
142 "NativeThreadLinux::%s tid %" PRIu64
143 " in state %s cannot answer stop reason",
148 llvm_unreachable(
"unhandled StateType!");
152 uint32_t watch_flags,
bool hardware) {
154 return Status(
"not implemented");
163 return Status(
"Setting hardware watchpoint failed.");
172 uint32_t wp_index = wp->second;
176 return Status(
"Clearing hardware watchpoint failed.");
191 return Status(
"Setting hardware breakpoint failed.");
202 uint32_t bp_index = bp->second;
208 return Status(
"Clearing hardware breakpoint failed.");
212 const StateType new_state = StateType::eStateRunning;
226 for (
const auto &pair : watchpoint_map) {
227 const auto &wp = pair.second;
228 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
238 for (
const auto &pair : hw_breakpoint_map) {
239 const auto &bp = pair.second;
250 reinterpret_cast<void *
>(data));
254 const StateType new_state = StateType::eStateStepping;
274 GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
276 m_tid,
nullptr,
reinterpret_cast<void *
>(data));
280 const siginfo_t *info) {
282 LLDB_LOGF(log,
"NativeThreadLinux::%s called with signal 0x%02" PRIx32,
283 __FUNCTION__, signo);
299#define SEGV_MTESERR 9
301 if (info->si_signo == SIGSEGV && info->si_code ==
SEGV_MTESERR)
310 int32_t allocation_tag_type = 0;
311 switch (
GetProcess().GetArchitecture().GetMachine()) {
313 case llvm::Triple::aarch64:
314 case llvm::Triple::aarch64_be:
324 llvm::consumeError(details.takeError());
333 std::stringstream ss;
334 std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
336 ss <<
" logical tag: 0x" << std::hex << manager->GetLogicalTag(fault_addr);
338 std::vector<uint8_t> allocation_tag_data;
344 1, allocation_tag_data);
347 llvm::Expected<std::vector<lldb::addr_t>> allocation_tag =
348 manager->UnpackTagsData(allocation_tag_data, 1);
349 if (allocation_tag) {
350 ss <<
" allocation tag: 0x" << std::hex << allocation_tag->front() <<
")";
352 llvm::consumeError(allocation_tag.takeError());
366 if (signo &&
m_state == StateType::eStateStopped &&
376 if (
m_state == StateType::eStateStepping)
382 const StateType new_state = StateType::eStateStopped;
390 LLDB_LOGF(log,
"NativeThreadLinux::%s()", __FUNCTION__);
411 std::ostringstream ostr;
435 return GetState() == StateType::eStateStopped &&
440 return GetState() == StateType::eStateStopped &&
455 is_vfork ? StopReason::eStopReasonVFork : StopReason::eStopReasonFork;
479 llvm::StringRef description) {
488 const StateType new_state = StateType::eStateExited;
504 "NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
505 ", tid: %" PRIu64
")",
506 __FUNCTION__, pid, tid);
513 "NativeThreadLinux::%s tgkill(%" PRIu64
", %" PRIu64
514 ", SIGSTOP) failed: %s",
515 __FUNCTION__, pid, tid, err.
AsCString());
529 if (new_state == old_state)
532 LLDB_LOG(log,
"pid={0}, tid={1}: changing from state {2} to {3}",
544llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
547 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
sizeof(siginfo_t));
550 if (!
error.Success())
551 return error.ToError();
552 return std::move(siginfo_buf);
static llvm::raw_ostream & error(Stream &strm)
std::string GetCrashReasonString(const siginfo_t &info)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define tgkill(pid, tid, sig)
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
lldb::pid_t GetID() const
virtual const HardwareBreakpointMap & GetHardwareBreakpointMap() const
virtual const NativeWatchpointList::WatchpointMap & GetWatchpointMap() const
NativeProcessProtocol & m_process
lldb::tid_t GetID() const
void SetErrorToErrno()
Set the current error to errno.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
bool Success() const
Test for success condition.
Manages communication with the inferior (debugee) process.
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.
virtual void InvalidateAllRegisters()
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 SetStoppedByVForkDone()
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
WatchpointIndexMap m_watchpoint_index_map
void SetStoppedByWatchpoint(uint32_t wp_index)
void SetStoppedBySignal(uint32_t signo, const siginfo_t *info=nullptr)
bool IsStoppedAtWatchpoint()
Status RemoveWatchpoint(lldb::addr_t addr) override
std::unique_ptr< NativeRegisterContextLinux > m_reg_context_up
void SetStoppedWithNoReason()
bool IsStoppedAtBreakpoint()
ThreadStopInfo m_stop_info
NativeProcessLinux & GetProcess()
Status SingleStep(uint32_t signo)
Single steps the thread.
WatchpointIndexMap m_hw_break_index_map
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.
lldb::StateType GetState() override
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override
std::string GetName() override
Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override
std::string m_stop_description
void SetStoppedByProcessorTrace(llvm::StringRef description)
NativeRegisterContextLinux & GetRegisterContext() override
Status Resume(uint32_t signo)
Resumes the thread.
void SetStoppedByBreakpoint()
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.
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.
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
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.
@ eStopReasonInstrumentation
@ eStopReasonPlanComplete
@ eStopReasonExec
Program was re-exec'ed.
@ eStopReasonProcessorTrace
@ eStopReasonThreadExiting
struct lldb_private::ThreadStopInfo::@11::@13 fork
struct lldb_private::ThreadStopInfo::@11::@12 exception
union lldb_private::ThreadStopInfo::@11 details