21#include <unordered_map>
46#include "llvm/ADT/ScopeExit.h"
47#include "llvm/Support/Errno.h"
48#include "llvm/Support/Error.h"
49#include "llvm/Support/FileSystem.h"
50#include "llvm/Support/Threading.h"
52#include <linux/unistd.h>
53#include <sys/socket.h>
54#include <sys/syscall.h>
70#define HWCAP2_MTE (1 << 18)
81 static bool is_supported;
82 static llvm::once_flag flag;
84 llvm::call_once(flag, [] {
87 uint32_t source = 0x47424742;
90 struct iovec local, remote;
91 remote.iov_base = &source;
92 local.iov_base = &dest;
93 remote.iov_len = local.iov_len =
sizeof source;
98 is_supported = (res ==
sizeof(source) && source == dest);
101 "Detected kernel support for process_vm_readv syscall. "
102 "Fast memory reads enabled.");
105 "syscall process_vm_readv failed (error: {0}). Fast memory "
107 llvm::sys::StrError());
119 LLDB_LOG(log,
"setting STDIN to '{0}'", action->GetFileSpec());
121 LLDB_LOG(log,
"leaving STDIN as is");
124 LLDB_LOG(log,
"setting STDOUT to '{0}'", action->GetFileSpec());
126 LLDB_LOG(log,
"leaving STDOUT as is");
129 LLDB_LOG(log,
"setting STDERR to '{0}'", action->GetFileSpec());
131 LLDB_LOG(log,
"leaving STDERR as is");
136 LLDB_LOG(log,
"arg {0}: '{1}'", i, *args);
140 uint8_t *ptr = (uint8_t *)bytes;
142 for (uint32_t i = 0; i < loop_count; i++) {
155 case PTRACE_POKETEXT: {
160 case PTRACE_POKEDATA: {
165 case PTRACE_POKEUSER: {
180 case PTRACE_SETSIGINFO: {
197 "Size of long must be larger than ptrace word size");
204 int status = fcntl(fd, F_GETFL);
210 if (fcntl(fd, F_SETFL, status | flags) == -1) {
220 if (
auto E = ptrace_scope.takeError()) {
222 LLDB_LOG(log,
"error reading value of ptrace_scope: {0}", E);
226 return original_error;
230 switch (*ptrace_scope) {
233 return llvm::createStringError(
234 std::error_code(errno, std::generic_category()),
235 "The current value of ptrace_scope is %d, which can cause ptrace to "
236 "fail to attach to a running process. To fix this, run:\n"
237 "\tsudo sysctl -w kernel.yama.ptrace_scope=0\n"
238 "For more information, see: "
239 "https://www.kernel.org/doc/Documentation/security/Yama.txt.",
242 return llvm::createStringError(
243 std::error_code(errno, std::generic_category()),
244 "The current value of ptrace_scope is 3, which will cause ptrace to "
245 "fail to attach to a running process. This value cannot be changed "
246 "without rebooting.\n"
247 "For more information, see: "
248 "https://www.kernel.org/doc/Documentation/security/Yama.txt.");
251 return original_error;
263llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
276 LLDB_LOG(log,
"failed to launch process: {0}", status);
282 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
285 if (!WIFSTOPPED(wstatus)) {
286 LLDB_LOG(log,
"Could not sync with inferior process: wstatus={1}",
288 return llvm::make_error<StringError>(
"Could not sync with inferior process",
289 llvm::inconvertibleErrorCode());
291 LLDB_LOG(log,
"inferior started, now in stopped state");
295 LLDB_LOG(log,
"failed to set default ptrace options: {0}", status);
299 llvm::Expected<ArchSpec> arch_or =
302 return arch_or.takeError();
306 *arch_or, *
this, {pid}));
309llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
317 return tids_or.takeError();
318 ArrayRef<::pid_t> tids = *tids_or;
319 llvm::Expected<ArchSpec> arch_or =
322 return arch_or.takeError();
324 return std::unique_ptr<NativeProcessLinux>(
344static std::optional<std::pair<lldb::pid_t, WaitStatus>>
WaitPid() {
348 ::pid_t wait_pid = llvm::sys::RetryAfterSignal(
349 -1, ::waitpid, -1, &status, __WALL | __WNOTHREAD | WNOHANG);
354 if (wait_pid == -1) {
362 LLDB_LOG(log,
"waitpid(-1, &status, _) = {0}, status = {1}", wait_pid,
364 return std::make_pair(wait_pid, wait_status);
391 m_unowned_threads.insert(pid);
393 LLDB_LOG(log,
"Ignoring waitpid event {0} for pid {1}", status, pid);
402 if (m_unowned_threads.erase(tid))
408 "received clone event for tid {0}. tid not tracked yet, "
409 "waiting for it to appear...",
412 llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, &status, __WALL);
419 "waitpid({0}, &status, __WALL) => {1} (errno: {2}, status = {3})",
428 llvm::ArrayRef<::pid_t> tids)
437 for (
const auto &tid : tids) {
444 SetState(StateType::eStateStopped,
false);
455 for (Host::TidMap::iterator it = tids_to_attach.begin();
456 it != tids_to_attach.end();) {
457 if (it->second ==
false) {
466 it = tids_to_attach.erase(it);
478 llvm::sys::RetryAfterSignal(-1, ::waitpid, tid,
nullptr, __WALL);
484 if (errno == ESRCH) {
485 it = tids_to_attach.erase(it);
488 return llvm::errorCodeToError(
489 std::error_code(errno, std::generic_category()));
495 LLDB_LOG(log,
"adding tid = {0}", tid);
504 size_t tid_count = tids_to_attach.size();
506 return llvm::make_error<StringError>(
"No such process",
507 llvm::inconvertibleErrorCode());
509 std::vector<::pid_t> tids;
510 tids.reserve(tid_count);
511 for (
const auto &p : tids_to_attach)
512 tids.push_back(p.first);
513 return std::move(tids);
517 long ptrace_opts = 0;
521 ptrace_opts |= PTRACE_O_TRACEEXIT;
524 ptrace_opts |= PTRACE_O_TRACECLONE;
528 ptrace_opts |= PTRACE_O_TRACEEXEC;
531 ptrace_opts |= PTRACE_O_TRACEFORK;
534 ptrace_opts |= PTRACE_O_TRACEVFORK;
538 ptrace_opts |= PTRACE_O_TRACEVFORKDONE;
540 return PtraceWrapper(PTRACE_SETOPTIONS, pid,
nullptr, (
void *)ptrace_opts);
545 if (pid ==
GetID() &&
564 const bool is_main_thread = (thread.
GetID() ==
GetID());
569 "got exit status({0}) , tid = {1} ({2} main thread), process "
571 status, thread.
GetID(), is_main_thread ?
"is" :
"is not",
577 assert(!is_main_thread &&
"Main thread exits handled elsewhere");
585 if (info_err.Success()) {
592 if (info_err.GetError() == EINVAL) {
603 "received a group stop for pid {0} tid {1}. Transparent "
604 "handling of group stops not supported, resuming the "
618 "GetSignalInfo({0}) failed: {1}, status = {2}, main_thread = "
619 "{3}. Expecting WIFEXITED soon.",
620 thread.
GetID(), info_err, status, is_main_thread);
628 const bool is_main_thread = (thread.
GetID() ==
GetID());
630 assert(info.si_signo ==
SIGTRAP &&
"Unexpected child signal!");
632 switch (info.si_code) {
633 case (
SIGTRAP | (PTRACE_EVENT_FORK << 8)):
634 case (
SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
635 case (
SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
641 unsigned long event_message = 0;
644 "pid {0} received clone() event but GetEventMessage failed "
645 "so we don't know the new pid/tid",
655 case (
SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
656 LLDB_LOG(log,
"received exec event, code = {0}", info.si_code ^
SIGTRAP);
663 LLDB_LOG(log,
"exec received, stop tracking all but main thread");
665 llvm::erase_if(
m_threads, [&](std::unique_ptr<NativeThreadProtocol> &t) {
666 return t->GetID() !=
GetID();
672 main_thread->SetStoppedByExec();
686 case (
SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
692 unsigned long data = 0;
697 "received PTRACE_EVENT_EXIT, data = {0:x}, WIFEXITED={1}, "
698 "WIFSIGNALED={2}, pid = {3}, main_thread = {4}",
699 data, WIFEXITED(data), WIFSIGNALED(data), thread.
GetID(),
714 if (is_main_thread) {
724 case (
SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
741 wp_index, (uintptr_t)info.si_addr);
744 "received error while checking for watchpoint hits, pid = "
755 bp_index, (uintptr_t)info.si_addr);
757 LLDB_LOG(log,
"received error while checking for hardware "
758 "breakpoint hits, pid = {0}, error = {1}",
781 "received error while checking for watchpoint hits, pid = "
799 "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}, resuming",
807 LLDB_LOG(log,
"received unknown SIGTRAP stop event ({0}, pid {1} tid {2}",
816 LLDB_LOG(log,
"received trace event, pid = {0}", thread.
GetID());
826 LLDB_LOG(log,
"received breakpoint event, pid = {0}", thread.
GetID());
833 auto stepping_with_bp_it =
836 stepping_with_bp_it->second == reg_ctx.
GetPC())
845 LLDB_LOG(log,
"received watchpoint event, pid = {0}, wp_index = {1}",
846 thread.
GetID(), wp_index);
859 const int signo = info.si_signo;
860 const bool is_from_llgs = info.si_pid == getpid();
875 "received signal {0} ({1}) with code {2}, (siginfo pid = {3}, "
876 "waitpid pid = {4})",
881 if (is_from_llgs && (info.si_code == SI_TKILL) && (signo ==
SIGSTOP)) {
914 LLDB_LOG(log,
"failed to resume thread {0}: {1}", thread.
GetID(),
919 "pid {0} tid {1}, thread was already marked as a stopped "
920 "state (state={2}), leaving stop signal as is",
947 LLDB_LOG(log,
"parent_tid={0}, child_pid={1}, event={2}", parent.
GetID(),
953 case PTRACE_EVENT_CLONE: {
959 if (tgid_ret != child_pid) {
961 assert(!tgid_ret || *tgid_ret ==
GetID());
972 case PTRACE_EVENT_FORK:
973 case PTRACE_EVENT_VFORK: {
974 bool is_vfork =
event == PTRACE_EVENT_VFORK;
988 child_process->Detach();
994 llvm_unreachable(
"unknown clone_info.event");
1015 if (software_single_step) {
1017 assert(thread &&
"thread list should not contain NULL threads");
1021 if (action ==
nullptr)
1034 assert(thread &&
"thread list should not contain NULL threads");
1039 if (action ==
nullptr) {
1040 LLDB_LOG(log,
"no action specified for pid {0} tid {1}",
GetID(),
1045 LLDB_LOG(log,
"processing resume action state {0} for pid {1} tid {2}",
1048 switch (action->
state) {
1052 const int signo = action->
signal;
1054 action->
state, signo);
1057 "NativeProcessLinux::%s: failed to resume thread "
1058 "for pid %" PRIu64
", tid %" PRIu64
", error = %s",
1059 __FUNCTION__,
GetID(), thread->GetID(),
error.AsCString());
1070 "NativeProcessLinux::%s (): unexpected state %s specified "
1071 "for pid %" PRIu64
", tid %" PRIu64,
1098 kill(
GetID(), SIGCONT);
1116 LLDB_LOG(log,
"sending signal {0} ({1}) to pid {1}", signo,
1119 if (kill(
GetID(), signo))
1133 LLDB_LOG(log,
"selecting running thread for interrupt target");
1137 const auto thread_state = thread->GetState();
1139 running_thread = thread.get();
1144 stopped_thread = thread.get();
1148 if (!running_thread && !stopped_thread) {
1149 Status error(
"found no running/stepping or live stopped threads as target "
1157 running_thread ? running_thread : stopped_thread;
1159 LLDB_LOG(log,
"pid {0} {1} tid {2} chosen for interrupt target",
GetID(),
1160 running_thread ?
"running" :
"stopped",
1161 deferred_signal_thread->
GetID());
1175 case StateType::eStateInvalid:
1176 case StateType::eStateExited:
1177 case StateType::eStateCrashed:
1178 case StateType::eStateDetached:
1179 case StateType::eStateUnloaded:
1181 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
1185 case StateType::eStateConnected:
1186 case StateType::eStateAttaching:
1187 case StateType::eStateLaunching:
1188 case StateType::eStateStopped:
1189 case StateType::eStateRunning:
1190 case StateType::eStateStepping:
1191 case StateType::eStateSuspended:
1235 "descending /proc/pid/maps entries detected, unexpected");
1253 range_info = proc_entry_info;
1279 LLDB_LOG(log,
"reusing {0} cached memory region entries",
1287 FileSpec file_spec(Info->GetName().GetCString());
1295 LLDB_LOG(log,
"failed to parse proc maps: {0}", Result);
1306 if (!BufferOrError) {
1308 return BufferOrError.getError();
1323 "failed to find any procfs maps entries, assuming no support "
1324 "for memory region metadata retrieval");
1328 LLDB_LOG(log,
"read {0} memory region entries from /proc/{1}/maps",
1338 LLDB_LOG(log,
"newBumpId={0}", newBumpId);
1339 LLDB_LOG(log,
"clearing {0} entries from memory region cache",
1344llvm::Expected<uint64_t>
1352 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1353 "No executable memory region found!");
1355 addr_t exe_addr = region_it->first.GetRange().GetRangeBase();
1366 return std::move(Err);
1367 auto restore_regs = llvm::make_scope_exit(
1370 llvm::SmallVector<uint8_t, 8> memory(syscall_data.
Insn.size());
1372 if (llvm::Error Err =
1373 ReadMemory(exe_addr, memory.data(), memory.size(), bytes_read)
1375 return std::move(Err);
1378 auto restore_mem = llvm::make_scope_exit(
1379 [&] {
WriteMemory(exe_addr, memory.data(), memory.size(), bytes_read); });
1381 if (llvm::Error Err = reg_ctx.
SetPC(exe_addr).
ToError())
1382 return std::move(Err);
1384 for (
const auto &zip : llvm::zip_first(args, syscall_data.
Args)) {
1385 if (llvm::Error Err =
1387 .WriteRegisterFromUnsigned(std::get<1>(zip), std::get<0>(zip))
1389 return std::move(Err);
1393 syscall_data.
Insn.size(), bytes_read)
1395 return std::move(Err);
1402 if (llvm::Error Err =
1404 return std::move(Err);
1407 ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, thread.
GetID(),
1409 if (wait_pid == -1) {
1410 return llvm::errorCodeToError(
1411 std::error_code(errno, std::generic_category()));
1413 assert((
unsigned)wait_pid == thread.
GetID());
1418 uint64_t errno_threshold =
1420 if (result > errno_threshold) {
1421 return llvm::errorCodeToError(
1422 std::error_code(-result & 0xfff, std::generic_category()));
1428llvm::Expected<addr_t>
1431 std::optional<NativeRegisterContextLinux::MmapData> mmap_data =
1434 return llvm::make_error<UnimplementedError>();
1437 assert((permissions & (ePermissionsReadable | ePermissionsWritable |
1438 ePermissionsExecutable)) == permissions &&
1439 "Unknown permission!");
1440 if (permissions & ePermissionsReadable)
1442 if (permissions & ePermissionsWritable)
1444 if (permissions & ePermissionsExecutable)
1447 llvm::Expected<uint64_t> Result =
1456 std::optional<NativeRegisterContextLinux::MmapData> mmap_data =
1459 return llvm::make_error<UnimplementedError>();
1463 return llvm::createStringError(llvm::errc::invalid_argument,
1464 "Memory not allocated by the debugger.");
1466 llvm::Expected<uint64_t> Result =
1467 Syscall({mmap_data->SysMunmap, addr, it->second});
1469 return Result.takeError();
1472 return llvm::Error::success();
1477 std::vector<uint8_t> &tags) {
1478 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
1492 range = details->manager->ExpandToGranule(range);
1495 size_t num_tags = range.
GetByteSize() / details->manager->GetGranuleSize();
1496 tags.resize(num_tags * details->manager->GetTagSizeInBytes());
1498 struct iovec tags_iovec;
1499 uint8_t *dest = tags.data();
1505 tags_iovec.iov_base = dest;
1506 tags_iovec.iov_len = num_tags;
1510 reinterpret_cast<void *
>(read_addr),
static_cast<void *
>(&tags_iovec),
1519 size_t tags_read = tags_iovec.iov_len;
1520 assert(tags_read && (tags_read <= num_tags));
1522 dest += tags_read * details->manager->GetTagSizeInBytes();
1523 read_addr += details->manager->GetGranuleSize() * tags_read;
1524 num_tags -= tags_read;
1532 const std::vector<uint8_t> &tags) {
1533 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
1547 range = details->manager->ExpandToGranule(range);
1550 llvm::Expected<std::vector<lldb::addr_t>> unpacked_tags_or_err =
1551 details->manager->UnpackTagsData(tags);
1552 if (!unpacked_tags_or_err)
1555 llvm::Expected<std::vector<lldb::addr_t>> repeated_tags_or_err =
1556 details->manager->RepeatTagsForRange(*unpacked_tags_or_err, range);
1557 if (!repeated_tags_or_err)
1561 llvm::Expected<std::vector<uint8_t>> final_tag_data =
1562 details->manager->PackTags(*repeated_tags_or_err);
1563 if (!final_tag_data)
1566 struct iovec tags_vec;
1567 uint8_t *src = final_tag_data->data();
1570 size_t num_tags = repeated_tags_or_err->size();
1574 while (num_tags > 0) {
1575 tags_vec.iov_base = src;
1576 tags_vec.iov_len = num_tags;
1580 reinterpret_cast<void *
>(write_addr),
static_cast<void *
>(&tags_vec), 0,
1589 size_t tags_written = tags_vec.iov_len;
1590 assert(tags_written && (tags_written <= num_tags));
1592 src += tags_written * details->manager->GetTagSizeInBytes();
1593 write_addr += details->manager->GetGranuleSize() * tags_written;
1594 num_tags -= tags_written;
1622llvm::Expected<llvm::ArrayRef<uint8_t>>
1626 static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
1627 static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
1630 case llvm::Triple::arm:
1631 switch (size_hint) {
1633 return llvm::ArrayRef(g_thumb_opcode);
1635 return llvm::ArrayRef(g_arm_opcode);
1637 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1638 "Unrecognised trap opcode size hint!");
1646 size_t &bytes_read) {
1648 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
1655 struct iovec local_iov, remote_iov;
1656 local_iov.iov_base = buf;
1657 local_iov.iov_len = size;
1658 remote_iov.iov_base =
reinterpret_cast<void *
>(addr);
1659 remote_iov.iov_len = size;
1664 if (read_result < 0)
1667 bytes_read = read_result;
1670 "process_vm_readv({0}, [iovec({1}, {2})], [iovec({3:x}, {2})], 1, "
1673 error > 0 ? llvm::sys::StrError(errno) :
"sucesss");
1676 unsigned char *dst =
static_cast<unsigned char *
>(buf);
1680 for (; bytes_read < size; bytes_read += remainder) {
1683 reinterpret_cast<void *
>(addr + bytes_read),
nullptr, 0, &data);
1687 remainder = size - bytes_read;
1691 memcpy(dst + bytes_read, &data, remainder);
1697 size_t size,
size_t &bytes_written) {
1698 const unsigned char *src =
static_cast<const unsigned char *
>(buf);
1703 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
1705 for (bytes_written = 0; bytes_written < size; bytes_written += remainder) {
1706 remainder = size - bytes_written;
1710 unsigned long data = 0;
1713 LLDB_LOG(log,
"[{0:x}]:{1:x}", addr, data);
1719 unsigned char buff[8];
1725 memcpy(buff, src, remainder);
1727 size_t bytes_written_rec;
1732 LLDB_LOG(log,
"[{0:x}]:{1:x} ({2:x})", addr, *(
const unsigned long *)src,
1733 *(
unsigned long *)buff);
1743 return PtraceWrapper(PTRACE_GETSIGINFO, tid,
nullptr, siginfo);
1747 unsigned long *message) {
1748 return PtraceWrapper(PTRACE_GETEVENTMSG, tid,
nullptr, message);
1760 assert(thread &&
"thread list should not contain NULL threads");
1761 if (thread->GetID() == thread_id) {
1774 LLDB_LOG(log,
"tid: {0}", thread_id);
1776 auto it = llvm::find_if(
m_threads, [&](
const auto &thread_up) {
1777 return thread_up.get() == &thread;
1798 LLDB_LOG(log,
"Failed to trace a new thread with intel-pt, tid = {0}. {1}",
1799 tid,
error.AsCString());
1808 "Failed to stop a destroyed thread with intel-pt, tid = {0}. {1}",
1809 tid,
error.AsCString());
1816 LLDB_LOG(log,
"pid {0} adding thread with tid {1}",
GetID(), thread_id);
1819 "attempted to add a thread by id that already exists");
1825 m_threads.push_back(std::make_unique<NativeThreadLinux>(*
this, thread_id));
1830 if (tracing_error.
Fail()) {
1847 FileSpec module_file_spec(module_path);
1852 if (it.second.GetFilename() == module_file_spec.
GetFilename()) {
1853 file_spec = it.second;
1858 "Module file (%s) not found in /proc/%" PRIu64
"/maps file!",
1871 if (it.second == file) {
1872 load_addr = it.first.GetRange().GetRangeBase();
1901 "about to resume tid {0} per explicit request but we have a "
1902 "pending stop notification (tid {1}) that is actively "
1903 "waiting for this thread to stop. Valid sequence of events?",
1914 return resume_result;
1923 LLDB_LOG(log,
"Unhandled state {0}.", state);
1924 llvm_unreachable(
"Unhandled state for resume");
1932 LLDB_LOG(log,
"about to process event: (triggering_tid: {0})",
1945 LLDB_LOG(log,
"event processing done");
1952 for (
const auto &thread_sp :
m_threads) {
1965 LLDB_LOG(log,
"pid = {0} remove stepping breakpoint: {1}",
1966 thread_info.first,
error);
1972 SetState(StateType::eStateStopped,
true);
1991 void *data,
size_t data_size,
2003 *(
unsigned int *)addr, data);
2014 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
2032 if (type ==
"intel-pt") {
2033 if (Expected<TraceIntelPTStartRequest> request =
2034 json::parse<TraceIntelPTStartRequest>(json_request,
2035 "TraceIntelPTStartRequest")) {
2038 return request.takeError();
2045 if (request.
type ==
"intel-pt")
2051 if (type ==
"intel-pt")
2058 if (request.
type ==
"intel-pt")
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGV(log,...)
static Status EnsureFDFlags(int fd, int flags)
static void MaybeLogLaunchInfo(const ProcessLaunchInfo &info)
static std::optional< std::pair< lldb::pid_t, WaitStatus > > WaitPid()
static constexpr unsigned k_ptrace_word_size
static void PtraceDisplayBytes(int &req, void *data, size_t data_size)
static Status EnsureFDFlags(int fd, int flags)
static llvm::Error AddPtraceScopeNote(llvm::Error original_error)
static void DisplayBytes(StreamString &s, void *bytes, uint32_t count)
static bool ProcessVmReadvSupported()
#define DEBUG_PTRACE_MAXBYTES
ssize_t process_vm_readv(::pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags)
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool IsMIPS() const
if MIPS architecture return true.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
const char ** GetConstArgumentVector() const
Gets the argument vector.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
const ConstString & GetFilename() const
Filename string const get accessor.
void Clear()
Clears the object state.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
lldb::pid_t GetProcessId() const
static bool FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach)
std::map< lldb::pid_t, bool > TidMap
static const char * GetSignalAsCString(int signo)
SignalHandleUP RegisterSignal(int signo, const Callback &callback, Status &error)
void SetMapped(OptionalBool val)
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetWritable(OptionalBool val)
Abstract class that extends NativeProcessProtocol with ELF specific logic.
void NotifyDidExec() override
Notify the delegate that an exec occurred.
virtual void NewSubprocess(NativeProcessProtocol *parent_process, std::unique_ptr< NativeProcessProtocol > child_process)=0
virtual llvm::Expected< TraceSupportedResponse > TraceSupported()
Get the processor tracing type supported for this process.
virtual llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request)
Get binary data given a trace technology and a data identifier.
lldb::pid_t GetID() const
virtual llvm::Error TraceStop(const TraceStopRequest &request)
Stop tracing a live process or its threads.
Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint)
virtual llvm::Expected< llvm::json::Value > TraceGetState(llvm::StringRef type)
Get the current tracing state of the process and its threads.
lldb::StateType GetState() const
void SetState(lldb::StateType state, bool notify_delegates=true)
NativeThreadProtocol * GetThreadByID(lldb::tid_t tid)
NativeThreadProtocol * GetCurrentThread()
void SetCurrentThreadID(lldb::tid_t tid)
std::vector< std::unique_ptr< NativeThreadProtocol > > m_threads
llvm::DenseSet< int > m_signals_to_ignore
virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange)
virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false)
NativeDelegate & m_delegate
void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread)
lldb::tid_t GetCurrentThreadID() const
Extension
Extension flag constants, returned by Manager::GetSupportedExtensions() and passed to SetEnabledExten...
virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
virtual llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint)
Extension m_enabled_extensions
virtual llvm::Error TraceStart(llvm::StringRef json_params, llvm::StringRef type)
Start tracing a process or its threads.
virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr)
std::unordered_map< lldb::addr_t, SoftwareBreakpoint > m_software_breakpoints
Status SetupSoftwareSingleStepping(NativeThreadProtocol &thread)
std::map< lldb::tid_t, lldb::addr_t > m_threads_stepping_with_breakpoint
lldb::addr_t ReadRegisterAsUnsigned(uint32_t reg, lldb::addr_t fail_value)
virtual Status GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
virtual Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)=0
lldb::addr_t GetPC(lldb::addr_t fail_value=LLDB_INVALID_ADDRESS)
virtual Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp)=0
Status SetPC(lldb::addr_t pc)
virtual Status GetHardwareBreakHitIndex(uint32_t &bp_index, lldb::addr_t trap_addr)
lldb::tid_t GetID() const
PseudoTerminal & GetPTY()
const FileAction * GetFileActionForFD(int fd) const
HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) override
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
const ResumeAction * GetActionForThread(lldb::tid_t tid, bool default_ok) const
static Status FromErrno()
Set the current error to errno.
Status Clone() const
Don't call this function in new code.
ValueType GetError() const
Access the error value.
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
const char * GetData() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
llvm::Expected< std::vector< uint8_t > > GetBinaryData(const TraceGetBinaryDataRequest &request)
Implementation of the jLLDBTraceGetBinaryData packet.
llvm::Error TraceStop(const TraceStopRequest &request)
Implementation of the jLLDBTraceStop packet.
static bool IsSupported()
llvm::Error TraceStart(const TraceIntelPTStartRequest &request)
Implementation of the jLLDBTraceStart packet.
llvm::Error OnThreadCreated(lldb::tid_t tid)
If "process tracing" is enabled, then trace the given thread.
llvm::Error OnThreadDestroyed(lldb::tid_t tid)
Stops tracing a tracing upon a destroy event.
void Clear()
Dispose of all traces.
llvm::Expected< llvm::json::Value > GetState()
Implementation of the jLLDBTraceGetState packet.
void ProcessWillResume()
To be invoked before the process will resume, so that we can capture the first instructions after the...
void ProcessDidStop()
To be invoked as soon as we know the process stopped.
Manager(MainLoop &mainloop)
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override
Attach to an existing process.
MainLoop::SignalHandleUP m_sigchld_handle
void AddProcess(NativeProcessLinux &process)
Extension GetSupportedExtensions() const override
Get the bitmask of extensions supported by this process plugin.
void CollectThread(::pid_t tid)
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate) override
Launch a process for debugging.
Manages communication with the inferior (debugee) process.
void MonitorBreakpoint(NativeThreadLinux &thread)
llvm::Expected< lldb::addr_t > AllocateMemory(size_t size, uint32_t permissions) override
void DoStopIDBumped(uint32_t newBumpId) override
llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override
Get binary data given a trace technology and a data identifier.
NativeThreadLinux * GetThreadByID(lldb::tid_t id)
llvm::Error DeallocateMemory(lldb::addr_t addr) override
Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr) override
Status NotifyTracersOfNewThread(lldb::tid_t tid)
Start tracing a new thread if process tracing is enabled.
const ArchSpec & GetArchitecture() const override
Status GetEventMessage(lldb::tid_t tid, unsigned long *message)
Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) corresponding to the given thread ID...
IntelPTCollector m_intel_pt_collector
Manages Intel PT process and thread traces.
llvm::Error TraceStart(llvm::StringRef json_request, llvm::StringRef type) override
Tracing These methods implement the jLLDBTrace packets.
lldb::tid_t m_pending_notification_tid
bool MonitorClone(NativeThreadLinux &parent, lldb::pid_t child_pid, int event)
void SignalIfAllThreadsStopped()
llvm::DenseMap< lldb::addr_t, lldb::addr_t > m_allocated_memory
Inferior memory (allocated by us) and its size.
Status Interrupt() override
Tells a process to interrupt all operations as if by a Ctrl-C.
std::vector< std::pair< MemoryRegionInfo, FileSpec > > m_mem_region_cache
void ThreadWasCreated(NativeThreadLinux &thread)
bool HasThreadNoLock(lldb::tid_t thread_id)
llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint) override
void NotifyTracersProcessWillResume() override
Notify tracers that the target process will resume.
void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread)
Status SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override
llvm::Expected< TraceSupportedResponse > TraceSupported() override
Get the processor tracing type supported for this process.
void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index)
bool TryHandleWaitStatus(lldb::pid_t pid, WaitStatus status)
llvm::Error TraceStop(const TraceStopRequest &request) override
Stop tracing a live process or its threads.
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override
Status Resume(const ResumeActionList &resume_actions) override
llvm::Expected< llvm::json::Value > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false) override
bool SupportHardwareSingleStepping() const
void StopTrackingThread(NativeThreadLinux &thread)
NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, Manager &manager, llvm::ArrayRef<::pid_t > tids)
Status NotifyTracersOfThreadDestroyed(lldb::tid_t tid)
Stop tracing threads upon a destroy event.
Status PopulateMemoryRegionCache()
void NotifyTracersProcessDidStop() override
Notify tracers that the target process just stopped.
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override
static Status SetDefaultPtraceOpts(const lldb::pid_t)
void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread)
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 WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len, const std::vector< uint8_t > &tags) override
size_t UpdateThreads() override
LazyBool m_supports_mem_region
Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len, std::vector< uint8_t > &tags) override
NativeThreadLinux * GetCurrentThread()
void MonitorTrace(NativeThreadLinux &thread)
void StopRunningThreads(lldb::tid_t triggering_tid)
Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo)
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override
NativeThreadLinux & AddThread(lldb::tid_t thread_id, bool resume)
Create a new thread.
static llvm::Expected< std::vector<::pid_t > > Attach(::pid_t pid)
llvm::Expected< uint64_t > Syscall(llvm::ArrayRef< uint64_t > args)
Status Signal(int signo) override
Sends a process a UNIX signal signal.
Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) override
void MonitorCallback(NativeThreadLinux &thread, WaitStatus status)
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 std::optional< MmapData > GetMmapData()
Return the architecture-specific data needed to make mmap syscalls, if they are supported.
static llvm::Expected< ArchSpec > DetermineArchitecture(lldb::tid_t tid)
virtual std::optional< SyscallData > GetSyscallData()
Return architecture-specific data needed to make inferior syscalls, if they are supported.
void SetStoppedByVForkDone()
void SetStoppedByWatchpoint(uint32_t wp_index)
void SetStoppedBySignal(uint32_t signo, const siginfo_t *info=nullptr)
void SetStoppedWithNoReason()
Status SingleStep(uint32_t signo)
Single steps the thread.
lldb::StateType GetState() override
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)
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_INDEX32
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
llvm::Expected< int > GetPtraceScope()
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.
std::optional< lldb::pid_t > getPIDForTID(lldb::pid_t tid)
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.
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
std::function< bool(llvm::Expected< MemoryRegionInfo >)> LinuxMapCallback
void ParseLinuxMapRegions(llvm::StringRef linux_map, LinuxMapCallback const &callback)
void ParseLinuxSMapRegions(llvm::StringRef linux_smap, LinuxMapCallback const &callback)
StateType
Process and Thread States.
@ 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.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eErrorTypePOSIX
POSIX error codes.
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
bool Contains(BaseType r) const
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
void SetByteSize(SizeType s)
jLLDBTraceGetBinaryData gdb-remote packet
std::string type
Tracing technology name, e.g. intel-pt, arm-coresight.
jLLDBTraceStop gdb-remote packet
std::string type
Tracing technology name, e.g. intel-pt, arm-coresight.
jLLDBTraceSupported gdb-remote packet
static WaitStatus Decode(int wstatus)
llvm::ArrayRef< uint8_t > Insn
The syscall instruction.
uint32_t Result
Register containing the syscall result.
llvm::ArrayRef< uint32_t > Args
Registers used for syscall arguments.