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);
206 error.SetErrorToErrno();
210 if (fcntl(fd, F_SETFL, status | flags) == -1) {
211 error.SetErrorToErrno();
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());
842 LLDB_LOG(log,
"received watchpoint event, pid = {0}, wp_index = {1}",
843 thread.
GetID(), wp_index);
856 const int signo = info.si_signo;
857 const bool is_from_llgs = info.si_pid == getpid();
872 "received signal {0} ({1}) with code {2}, (siginfo pid = {3}, "
873 "waitpid pid = {4})",
878 if (is_from_llgs && (info.si_code == SI_TKILL) && (signo ==
SIGSTOP)) {
911 LLDB_LOG(log,
"failed to resume thread {0}: {1}", thread.
GetID(),
916 "pid {0} tid {1}, thread was already marked as a stopped "
917 "state (state={2}), leaving stop signal as is",
944 LLDB_LOG(log,
"parent_tid={0}, child_pid={1}, event={2}", parent.
GetID(),
950 case PTRACE_EVENT_CLONE: {
956 if (tgid_ret != child_pid) {
958 assert(!tgid_ret || *tgid_ret ==
GetID());
969 case PTRACE_EVENT_FORK:
970 case PTRACE_EVENT_VFORK: {
971 bool is_vfork =
event == PTRACE_EVENT_VFORK;
985 child_process->Detach();
991 llvm_unreachable(
"unknown clone_info.event");
1012 if (software_single_step) {
1014 assert(thread &&
"thread list should not contain NULL threads");
1018 if (action ==
nullptr)
1031 assert(thread &&
"thread list should not contain NULL threads");
1036 if (action ==
nullptr) {
1037 LLDB_LOG(log,
"no action specified for pid {0} tid {1}",
GetID(),
1042 LLDB_LOG(log,
"processing resume action state {0} for pid {1} tid {2}",
1045 switch (action->
state) {
1049 const int signo = action->
signal;
1051 action->
state, signo);
1053 return Status(
"NativeProcessLinux::%s: failed to resume thread "
1054 "for pid %" PRIu64
", tid %" PRIu64
", error = %s",
1055 __FUNCTION__,
GetID(), thread->GetID(),
1066 return Status(
"NativeProcessLinux::%s (): unexpected state %s specified "
1067 "for pid %" PRIu64
", tid %" PRIu64,
1080 error.SetErrorToErrno();
1094 kill(
GetID(), SIGCONT);
1112 LLDB_LOG(log,
"sending signal {0} ({1}) to pid {1}", signo,
1115 if (kill(
GetID(), signo))
1116 error.SetErrorToErrno();
1129 LLDB_LOG(log,
"selecting running thread for interrupt target");
1133 const auto thread_state = thread->GetState();
1135 running_thread = thread.get();
1140 stopped_thread = thread.get();
1144 if (!running_thread && !stopped_thread) {
1145 Status error(
"found no running/stepping or live stopped threads as target "
1153 running_thread ? running_thread : stopped_thread;
1155 LLDB_LOG(log,
"pid {0} {1} tid {2} chosen for interrupt target",
GetID(),
1156 running_thread ?
"running" :
"stopped",
1157 deferred_signal_thread->
GetID());
1171 case StateType::eStateInvalid:
1172 case StateType::eStateExited:
1173 case StateType::eStateCrashed:
1174 case StateType::eStateDetached:
1175 case StateType::eStateUnloaded:
1177 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
1181 case StateType::eStateConnected:
1182 case StateType::eStateAttaching:
1183 case StateType::eStateLaunching:
1184 case StateType::eStateStopped:
1185 case StateType::eStateRunning:
1186 case StateType::eStateStepping:
1187 case StateType::eStateSuspended:
1193 error.SetErrorToErrno();
1212 return Status(
"unsupported");
1231 "descending /proc/pid/maps entries detected, unexpected");
1249 range_info = proc_entry_info;
1275 LLDB_LOG(log,
"reusing {0} cached memory region entries",
1283 FileSpec file_spec(Info->GetName().GetCString());
1289 Result = Info.takeError();
1291 LLDB_LOG(log,
"failed to parse proc maps: {0}", Result);
1302 if (!BufferOrError) {
1304 return BufferOrError.getError();
1319 "failed to find any procfs maps entries, assuming no support "
1320 "for memory region metadata retrieval");
1321 return Status(
"not supported");
1324 LLDB_LOG(log,
"read {0} memory region entries from /proc/{1}/maps",
1334 LLDB_LOG(log,
"newBumpId={0}", newBumpId);
1335 LLDB_LOG(log,
"clearing {0} entries from memory region cache",
1340llvm::Expected<uint64_t>
1348 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1349 "No executable memory region found!");
1351 addr_t exe_addr = region_it->first.GetRange().GetRangeBase();
1362 return std::move(Err);
1363 auto restore_regs = llvm::make_scope_exit(
1366 llvm::SmallVector<uint8_t, 8> memory(syscall_data.
Insn.size());
1368 if (llvm::Error Err =
1369 ReadMemory(exe_addr, memory.data(), memory.size(), bytes_read)
1371 return std::move(Err);
1374 auto restore_mem = llvm::make_scope_exit(
1375 [&] {
WriteMemory(exe_addr, memory.data(), memory.size(), bytes_read); });
1377 if (llvm::Error Err = reg_ctx.
SetPC(exe_addr).
ToError())
1378 return std::move(Err);
1380 for (
const auto &zip : llvm::zip_first(args, syscall_data.
Args)) {
1381 if (llvm::Error Err =
1383 .WriteRegisterFromUnsigned(std::get<1>(zip), std::get<0>(zip))
1385 return std::move(Err);
1389 syscall_data.
Insn.size(), bytes_read)
1391 return std::move(Err);
1398 if (llvm::Error Err =
1400 return std::move(Err);
1403 ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, thread.
GetID(),
1405 if (wait_pid == -1) {
1406 return llvm::errorCodeToError(
1407 std::error_code(errno, std::generic_category()));
1409 assert((
unsigned)wait_pid == thread.
GetID());
1414 uint64_t errno_threshold =
1416 if (result > errno_threshold) {
1417 return llvm::errorCodeToError(
1418 std::error_code(-result & 0xfff, std::generic_category()));
1424llvm::Expected<addr_t>
1427 std::optional<NativeRegisterContextLinux::MmapData> mmap_data =
1430 return llvm::make_error<UnimplementedError>();
1433 assert((permissions & (ePermissionsReadable | ePermissionsWritable |
1434 ePermissionsExecutable)) == permissions &&
1435 "Unknown permission!");
1436 if (permissions & ePermissionsReadable)
1438 if (permissions & ePermissionsWritable)
1440 if (permissions & ePermissionsExecutable)
1443 llvm::Expected<uint64_t> Result =
1452 std::optional<NativeRegisterContextLinux::MmapData> mmap_data =
1455 return llvm::make_error<UnimplementedError>();
1459 return llvm::createStringError(llvm::errc::invalid_argument,
1460 "Memory not allocated by the debugger.");
1462 llvm::Expected<uint64_t> Result =
1463 Syscall({mmap_data->SysMunmap, addr, it->second});
1465 return Result.takeError();
1468 return llvm::Error::success();
1473 std::vector<uint8_t> &tags) {
1474 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
1477 return Status(details.takeError());
1488 range = details->manager->ExpandToGranule(range);
1491 size_t num_tags = range.
GetByteSize() / details->manager->GetGranuleSize();
1492 tags.resize(num_tags * details->manager->GetTagSizeInBytes());
1494 struct iovec tags_iovec;
1495 uint8_t *dest = tags.data();
1501 tags_iovec.iov_base = dest;
1502 tags_iovec.iov_len = num_tags;
1506 reinterpret_cast<void *
>(read_addr),
static_cast<void *
>(&tags_iovec),
1515 size_t tags_read = tags_iovec.iov_len;
1516 assert(tags_read && (tags_read <= num_tags));
1518 dest += tags_read * details->manager->GetTagSizeInBytes();
1519 read_addr += details->manager->GetGranuleSize() * tags_read;
1520 num_tags -= tags_read;
1528 const std::vector<uint8_t> &tags) {
1529 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
1532 return Status(details.takeError());
1543 range = details->manager->ExpandToGranule(range);
1546 llvm::Expected<std::vector<lldb::addr_t>> unpacked_tags_or_err =
1547 details->manager->UnpackTagsData(tags);
1548 if (!unpacked_tags_or_err)
1549 return Status(unpacked_tags_or_err.takeError());
1551 llvm::Expected<std::vector<lldb::addr_t>> repeated_tags_or_err =
1552 details->manager->RepeatTagsForRange(*unpacked_tags_or_err, range);
1553 if (!repeated_tags_or_err)
1554 return Status(repeated_tags_or_err.takeError());
1557 llvm::Expected<std::vector<uint8_t>> final_tag_data =
1558 details->manager->PackTags(*repeated_tags_or_err);
1559 if (!final_tag_data)
1560 return Status(final_tag_data.takeError());
1562 struct iovec tags_vec;
1563 uint8_t *src = final_tag_data->data();
1566 size_t num_tags = repeated_tags_or_err->size();
1570 while (num_tags > 0) {
1571 tags_vec.iov_base = src;
1572 tags_vec.iov_len = num_tags;
1576 reinterpret_cast<void *
>(write_addr),
static_cast<void *
>(&tags_vec), 0,
1585 size_t tags_written = tags_vec.iov_len;
1586 assert(tags_written && (tags_written <= num_tags));
1588 src += tags_written * details->manager->GetTagSizeInBytes();
1589 write_addr += details->manager->GetGranuleSize() * tags_written;
1590 num_tags -= tags_written;
1618llvm::Expected<llvm::ArrayRef<uint8_t>>
1622 static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
1623 static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
1626 case llvm::Triple::arm:
1627 switch (size_hint) {
1629 return llvm::ArrayRef(g_thumb_opcode);
1631 return llvm::ArrayRef(g_arm_opcode);
1633 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1634 "Unrecognised trap opcode size hint!");
1642 size_t &bytes_read) {
1647 struct iovec local_iov, remote_iov;
1648 local_iov.iov_base = buf;
1649 local_iov.iov_len = size;
1650 remote_iov.iov_base =
reinterpret_cast<void *
>(addr);
1651 remote_iov.iov_len = size;
1655 const bool success = bytes_read == size;
1659 "using process_vm_readv to read {0} bytes from inferior "
1660 "address {1:x}: {2}",
1661 size, addr, success ?
"Success" : llvm::sys::StrError(errno));
1669 unsigned char *dst =
static_cast<unsigned char *
>(buf);
1674 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
1676 for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
1682 remainder = size - bytes_read;
1686 memcpy(dst, &data, remainder);
1688 LLDB_LOG(log,
"[{0:x}]:{1:x}", addr, data);
1696 size_t size,
size_t &bytes_written) {
1697 const unsigned char *src =
static_cast<const unsigned char *
>(buf);
1702 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
1704 for (bytes_written = 0; bytes_written < size; bytes_written += remainder) {
1705 remainder = size - bytes_written;
1709 unsigned long data = 0;
1712 LLDB_LOG(log,
"[{0:x}]:{1:x}", addr, data);
1718 unsigned char buff[8];
1724 memcpy(buff, src, remainder);
1726 size_t bytes_written_rec;
1731 LLDB_LOG(log,
"[{0:x}]:{1:x} ({2:x})", addr, *(
const unsigned long *)src,
1732 *(
unsigned long *)buff);
1742 return PtraceWrapper(PTRACE_GETSIGINFO, tid,
nullptr, siginfo);
1746 unsigned long *message) {
1747 return PtraceWrapper(PTRACE_GETEVENTMSG, tid,
nullptr, message);
1759 assert(thread &&
"thread list should not contain NULL threads");
1760 if (thread->GetID() == thread_id) {
1773 LLDB_LOG(log,
"tid: {0}", thread_id);
1775 auto it = llvm::find_if(
m_threads, [&](
const auto &thread_up) {
1776 return thread_up.get() == &thread;
1797 LLDB_LOG(log,
"Failed to trace a new thread with intel-pt, tid = {0}. {1}",
1798 tid,
error.AsCString());
1807 "Failed to stop a destroyed thread with intel-pt, tid = {0}. {1}",
1808 tid,
error.AsCString());
1815 LLDB_LOG(log,
"pid {0} adding thread with tid {1}",
GetID(), thread_id);
1818 "attempted to add a thread by id that already exists");
1824 m_threads.push_back(std::make_unique<NativeThreadLinux>(*
this, thread_id));
1829 if (tracing_error.
Fail()) {
1846 FileSpec module_file_spec(module_path);
1851 if (it.second.GetFilename() == module_file_spec.
GetFilename()) {
1852 file_spec = it.second;
1856 return Status(
"Module file (%s) not found in /proc/%" PRIu64
"/maps file!",
1869 if (it.second == file) {
1870 load_addr = it.first.GetRange().GetRangeBase();
1874 return Status(
"No load address found for specified file.");
1899 "about to resume tid {0} per explicit request but we have a "
1900 "pending stop notification (tid {1}) that is actively "
1901 "waiting for this thread to stop. Valid sequence of events?",
1909 const auto resume_result = thread.
Resume(signo);
1910 if (resume_result.Success())
1912 return resume_result;
1915 const auto step_result = thread.
SingleStep(signo);
1916 if (step_result.Success())
1921 LLDB_LOG(log,
"Unhandled state {0}.", state);
1922 llvm_unreachable(
"Unhandled state for resume");
1930 LLDB_LOG(log,
"about to process event: (triggering_tid: {0})",
1943 LLDB_LOG(log,
"event processing done");
1950 for (
const auto &thread_sp :
m_threads) {
1963 LLDB_LOG(log,
"pid = {0} remove stepping breakpoint: {1}",
1964 thread_info.first,
error);
1970 SetState(StateType::eStateStopped,
true);
1989 void *data,
size_t data_size,
2001 *(
unsigned int *)addr, data);
2007 error.SetErrorToErrno();
2012 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
2030 if (type ==
"intel-pt") {
2031 if (Expected<TraceIntelPTStartRequest> request =
2032 json::parse<TraceIntelPTStartRequest>(json_request,
2033 "TraceIntelPTStartRequest")) {
2036 return request.takeError();
2043 if (request.
type ==
"intel-pt")
2049 if (type ==
"intel-pt")
2056 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
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
ValueType GetError() const
Access the error value.
llvm::Error ToError() const
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.
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.