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, [] {
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;
257llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
271 LLDB_LOG(log,
"failed to launch process: {0}", status);
277 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
280 if (!WIFSTOPPED(wstatus)) {
281 LLDB_LOG(log,
"Could not sync with inferior process: wstatus={1}",
283 return llvm::make_error<StringError>(
"Could not sync with inferior process",
284 llvm::inconvertibleErrorCode());
286 LLDB_LOG(log,
"inferior started, now in stopped state");
290 LLDB_LOG(log,
"failed to set default ptrace options: {0}", status);
294 llvm::Expected<ArchSpec> arch_or =
297 return arch_or.takeError();
301 *arch_or, mainloop, {pid}));
304llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
313 return tids_or.takeError();
314 ArrayRef<::pid_t> tids = *tids_or;
315 llvm::Expected<ArchSpec> arch_or =
318 return arch_or.takeError();
321 pid, -1, native_delegate, *arch_or, mainloop, tids));
345 llvm::ArrayRef<::pid_t> tids)
358 for (
const auto &tid : tids) {
365 SetState(StateType::eStateStopped,
false);
379 for (Host::TidMap::iterator it = tids_to_attach.begin();
380 it != tids_to_attach.end();) {
381 if (it->second ==
false) {
390 it = tids_to_attach.erase(it);
402 llvm::sys::RetryAfterSignal(-1, ::waitpid, tid,
nullptr, __WALL);
408 if (errno == ESRCH) {
409 it = tids_to_attach.erase(it);
412 return llvm::errorCodeToError(
413 std::error_code(errno, std::generic_category()));
419 LLDB_LOG(log,
"adding tid = {0}", tid);
428 size_t tid_count = tids_to_attach.size();
430 return llvm::make_error<StringError>(
"No such process",
431 llvm::inconvertibleErrorCode());
433 std::vector<::pid_t> tids;
434 tids.reserve(tid_count);
435 for (
const auto &p : tids_to_attach)
436 tids.push_back(p.first);
437 return std::move(tids);
441 long ptrace_opts = 0;
445 ptrace_opts |= PTRACE_O_TRACEEXIT;
448 ptrace_opts |= PTRACE_O_TRACECLONE;
452 ptrace_opts |= PTRACE_O_TRACEEXEC;
455 ptrace_opts |= PTRACE_O_TRACEFORK;
458 ptrace_opts |= PTRACE_O_TRACEVFORK;
462 ptrace_opts |= PTRACE_O_TRACEVFORKDONE;
464 return PtraceWrapper(PTRACE_SETOPTIONS, pid,
nullptr, (
void *)ptrace_opts);
474 const bool is_main_thread = (thread.
GetID() ==
GetID());
479 "got exit status({0}) , tid = {1} ({2} main thread), process "
481 status, thread.
GetID(), is_main_thread ?
"is" :
"is not",
487 assert(!is_main_thread &&
"Main thread exits handled elsewhere");
495 if (info_err.Success()) {
502 if (info_err.GetError() == EINVAL) {
513 "received a group stop for pid {0} tid {1}. Transparent "
514 "handling of group stops not supported, resuming the "
528 "GetSignalInfo({0}) failed: {1}, status = {2}, main_thread = "
529 "{3}. Expecting WIFEXITED soon.",
530 thread.
GetID(), info_err, status, is_main_thread);
541 "received clone event for pid {0}. pid not tracked yet, "
542 "waiting for it to appear...",
545 llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &status, __WALL);
552 "waitpid({0}, &status, __WALL) => {1} (errno: {2}, status = {3})",
559 const bool is_main_thread = (thread.
GetID() ==
GetID());
561 assert(info.si_signo ==
SIGTRAP &&
"Unexpected child signal!");
563 switch (info.si_code) {
564 case (
SIGTRAP | (PTRACE_EVENT_FORK << 8)):
565 case (
SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
566 case (
SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
572 unsigned long event_message = 0;
575 "pid {0} received clone() event but GetEventMessage failed "
576 "so we don't know the new pid/tid",
586 case (
SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
587 LLDB_LOG(log,
"received exec event, code = {0}", info.si_code ^
SIGTRAP);
594 LLDB_LOG(log,
"exec received, stop tracking all but main thread");
596 llvm::erase_if(
m_threads, [&](std::unique_ptr<NativeThreadProtocol> &t) {
597 return t->GetID() !=
GetID();
603 main_thread->SetStoppedByExec();
617 case (
SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
623 unsigned long data = 0;
628 "received PTRACE_EVENT_EXIT, data = {0:x}, WIFEXITED={1}, "
629 "WIFSIGNALED={2}, pid = {3}, main_thread = {4}",
630 data, WIFEXITED(data), WIFSIGNALED(data), thread.
GetID(),
645 if (is_main_thread) {
655 case (
SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
672 wp_index, (uintptr_t)info.si_addr);
675 "received error while checking for watchpoint hits, pid = "
686 bp_index, (uintptr_t)info.si_addr);
688 LLDB_LOG(log,
"received error while checking for hardware "
689 "breakpoint hits, pid = {0}, error = {1}",
712 "received error while checking for watchpoint hits, pid = "
730 "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}, resuming",
738 LLDB_LOG(log,
"received unknown SIGTRAP stop event ({0}, pid {1} tid {2}",
747 LLDB_LOG(log,
"received trace event, pid = {0}", thread.
GetID());
757 LLDB_LOG(log,
"received breakpoint event, pid = {0}", thread.
GetID());
773 LLDB_LOG(log,
"received watchpoint event, pid = {0}, wp_index = {1}",
774 thread.
GetID(), wp_index);
787 const int signo = info.si_signo;
788 const bool is_from_llgs = info.si_pid == getpid();
803 "received signal {0} ({1}) with code {2}, (siginfo pid = {3}, "
804 "waitpid pid = {4})",
809 if (is_from_llgs && (info.si_code == SI_TKILL) && (signo ==
SIGSTOP)) {
842 LLDB_LOG(log,
"failed to resume thread {0}: {1}", thread.
GetID(),
847 "pid {0} tid {1}, thread was already marked as a stopped "
848 "state (state={2}), leaving stop signal as is",
875 LLDB_LOG(log,
"parent_tid={0}, child_pid={1}, event={2}", parent.
GetID(),
881 case PTRACE_EVENT_CLONE: {
887 if (tgid_ret != child_pid) {
889 assert(!tgid_ret || *tgid_ret ==
GetID());
900 case PTRACE_EVENT_FORK:
901 case PTRACE_EVENT_VFORK: {
902 bool is_vfork =
event == PTRACE_EVENT_VFORK;
916 child_process->Detach();
922 llvm_unreachable(
"unknown clone_info.event");
943 if (software_single_step) {
945 assert(thread &&
"thread list should not contain NULL threads");
949 if (action ==
nullptr)
962 assert(thread &&
"thread list should not contain NULL threads");
967 if (action ==
nullptr) {
968 LLDB_LOG(log,
"no action specified for pid {0} tid {1}",
GetID(),
973 LLDB_LOG(log,
"processing resume action state {0} for pid {1} tid {2}",
976 switch (action->
state) {
980 const int signo = action->
signal;
982 action->
state, signo);
984 return Status(
"NativeProcessLinux::%s: failed to resume thread "
985 "for pid %" PRIu64
", tid %" PRIu64
", error = %s",
986 __FUNCTION__,
GetID(), thread->GetID(),
997 return Status(
"NativeProcessLinux::%s (): unexpected state %s specified "
998 "for pid %" PRIu64
", tid %" PRIu64,
1011 error.SetErrorToErrno();
1042 LLDB_LOG(log,
"sending signal {0} ({1}) to pid {1}", signo,
1045 if (kill(
GetID(), signo))
1046 error.SetErrorToErrno();
1059 LLDB_LOG(log,
"selecting running thread for interrupt target");
1063 const auto thread_state = thread->GetState();
1065 running_thread = thread.get();
1070 stopped_thread = thread.get();
1074 if (!running_thread && !stopped_thread) {
1075 Status error(
"found no running/stepping or live stopped threads as target "
1083 running_thread ? running_thread : stopped_thread;
1085 LLDB_LOG(log,
"pid {0} {1} tid {2} chosen for interrupt target",
GetID(),
1086 running_thread ?
"running" :
"stopped",
1087 deferred_signal_thread->
GetID());
1101 case StateType::eStateInvalid:
1102 case StateType::eStateExited:
1103 case StateType::eStateCrashed:
1104 case StateType::eStateDetached:
1105 case StateType::eStateUnloaded:
1107 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
1111 case StateType::eStateConnected:
1112 case StateType::eStateAttaching:
1113 case StateType::eStateLaunching:
1114 case StateType::eStateStopped:
1115 case StateType::eStateRunning:
1116 case StateType::eStateStepping:
1117 case StateType::eStateSuspended:
1123 error.SetErrorToErrno();
1142 return Status(
"unsupported");
1161 "descending /proc/pid/maps entries detected, unexpected");
1179 range_info = proc_entry_info;
1205 LLDB_LOG(log,
"reusing {0} cached memory region entries",
1213 FileSpec file_spec(Info->GetName().GetCString());
1219 Result = Info.takeError();
1221 LLDB_LOG(log,
"failed to parse proc maps: {0}", Result);
1232 if (!BufferOrError) {
1234 return BufferOrError.getError();
1249 "failed to find any procfs maps entries, assuming no support "
1250 "for memory region metadata retrieval");
1251 return Status(
"not supported");
1254 LLDB_LOG(log,
"read {0} memory region entries from /proc/{1}/maps",
1264 LLDB_LOG(log,
"newBumpId={0}", newBumpId);
1265 LLDB_LOG(log,
"clearing {0} entries from memory region cache",
1270llvm::Expected<uint64_t>
1278 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1279 "No executable memory region found!");
1281 addr_t exe_addr = region_it->first.GetRange().GetRangeBase();
1290 WritableDataBufferSP registers_sp;
1292 return std::move(Err);
1293 auto restore_regs = llvm::make_scope_exit(
1296 llvm::SmallVector<uint8_t, 8> memory(syscall_data.
Insn.size());
1298 if (llvm::Error Err =
1299 ReadMemory(exe_addr, memory.data(), memory.size(), bytes_read)
1301 return std::move(Err);
1304 auto restore_mem = llvm::make_scope_exit(
1305 [&] {
WriteMemory(exe_addr, memory.data(), memory.size(), bytes_read); });
1307 if (llvm::Error Err = reg_ctx.
SetPC(exe_addr).
ToError())
1308 return std::move(Err);
1310 for (
const auto &zip : llvm::zip_first(args, syscall_data.
Args)) {
1311 if (llvm::Error Err =
1313 .WriteRegisterFromUnsigned(std::get<1>(zip), std::get<0>(zip))
1315 return std::move(Err);
1319 syscall_data.
Insn.size(), bytes_read)
1321 return std::move(Err);
1328 if (llvm::Error Err =
1330 return std::move(Err);
1333 ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, thread.
GetID(),
1335 if (wait_pid == -1) {
1336 return llvm::errorCodeToError(
1337 std::error_code(errno, std::generic_category()));
1339 assert((
unsigned)wait_pid == thread.
GetID());
1344 uint64_t errno_threshold =
1346 if (result > errno_threshold) {
1347 return llvm::errorCodeToError(
1348 std::error_code(-result & 0xfff, std::generic_category()));
1354llvm::Expected<addr_t>
1357 std::optional<NativeRegisterContextLinux::MmapData> mmap_data =
1360 return llvm::make_error<UnimplementedError>();
1363 assert((permissions & (ePermissionsReadable | ePermissionsWritable |
1364 ePermissionsExecutable)) == permissions &&
1365 "Unknown permission!");
1366 if (permissions & ePermissionsReadable)
1368 if (permissions & ePermissionsWritable)
1370 if (permissions & ePermissionsExecutable)
1373 llvm::Expected<uint64_t> Result =
1382 std::optional<NativeRegisterContextLinux::MmapData> mmap_data =
1385 return llvm::make_error<UnimplementedError>();
1389 return llvm::createStringError(llvm::errc::invalid_argument,
1390 "Memory not allocated by the debugger.");
1392 llvm::Expected<uint64_t> Result =
1393 Syscall({mmap_data->SysMunmap, addr, it->second});
1395 return Result.takeError();
1398 return llvm::Error::success();
1403 std::vector<uint8_t> &tags) {
1404 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
1407 return Status(details.takeError());
1418 range = details->manager->ExpandToGranule(range);
1421 size_t num_tags = range.
GetByteSize() / details->manager->GetGranuleSize();
1422 tags.resize(num_tags * details->manager->GetTagSizeInBytes());
1424 struct iovec tags_iovec;
1425 uint8_t *dest = tags.data();
1431 tags_iovec.iov_base = dest;
1432 tags_iovec.iov_len = num_tags;
1436 reinterpret_cast<void *
>(read_addr),
static_cast<void *
>(&tags_iovec),
1445 size_t tags_read = tags_iovec.iov_len;
1446 assert(tags_read && (tags_read <= num_tags));
1448 dest += tags_read * details->manager->GetTagSizeInBytes();
1449 read_addr += details->manager->GetGranuleSize() * tags_read;
1450 num_tags -= tags_read;
1458 const std::vector<uint8_t> &tags) {
1459 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
1462 return Status(details.takeError());
1473 range = details->manager->ExpandToGranule(range);
1476 llvm::Expected<std::vector<lldb::addr_t>> unpacked_tags_or_err =
1477 details->manager->UnpackTagsData(tags);
1478 if (!unpacked_tags_or_err)
1479 return Status(unpacked_tags_or_err.takeError());
1481 llvm::Expected<std::vector<lldb::addr_t>> repeated_tags_or_err =
1482 details->manager->RepeatTagsForRange(*unpacked_tags_or_err, range);
1483 if (!repeated_tags_or_err)
1484 return Status(repeated_tags_or_err.takeError());
1487 llvm::Expected<std::vector<uint8_t>> final_tag_data =
1488 details->manager->PackTags(*repeated_tags_or_err);
1489 if (!final_tag_data)
1490 return Status(final_tag_data.takeError());
1492 struct iovec tags_vec;
1493 uint8_t *src = final_tag_data->data();
1496 size_t num_tags = repeated_tags_or_err->size();
1500 while (num_tags > 0) {
1501 tags_vec.iov_base = src;
1502 tags_vec.iov_len = num_tags;
1506 reinterpret_cast<void *
>(write_addr),
static_cast<void *
>(&tags_vec), 0,
1515 size_t tags_written = tags_vec.iov_len;
1516 assert(tags_written && (tags_written <= num_tags));
1518 src += tags_written * details->manager->GetTagSizeInBytes();
1519 write_addr += details->manager->GetGranuleSize() * tags_written;
1520 num_tags -= tags_written;
1548llvm::Expected<llvm::ArrayRef<uint8_t>>
1552 static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
1553 static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
1556 case llvm::Triple::arm:
1557 switch (size_hint) {
1559 return llvm::ArrayRef(g_thumb_opcode);
1561 return llvm::ArrayRef(g_arm_opcode);
1563 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1564 "Unrecognised trap opcode size hint!");
1572 size_t &bytes_read) {
1577 struct iovec local_iov, remote_iov;
1578 local_iov.iov_base = buf;
1579 local_iov.iov_len = size;
1580 remote_iov.iov_base =
reinterpret_cast<void *
>(addr);
1581 remote_iov.iov_len = size;
1585 const bool success = bytes_read == size;
1589 "using process_vm_readv to read {0} bytes from inferior "
1590 "address {1:x}: {2}",
1591 size, addr, success ?
"Success" : llvm::sys::StrError(errno));
1599 unsigned char *dst =
static_cast<unsigned char *
>(buf);
1604 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
1606 for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
1612 remainder = size - bytes_read;
1616 memcpy(dst, &data, remainder);
1618 LLDB_LOG(log,
"[{0:x}]:{1:x}", addr, data);
1626 size_t size,
size_t &bytes_written) {
1627 const unsigned char *src =
static_cast<const unsigned char *
>(buf);
1632 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
1634 for (bytes_written = 0; bytes_written < size; bytes_written += remainder) {
1635 remainder = size - bytes_written;
1639 unsigned long data = 0;
1642 LLDB_LOG(log,
"[{0:x}]:{1:x}", addr, data);
1648 unsigned char buff[8];
1654 memcpy(buff, src, remainder);
1656 size_t bytes_written_rec;
1661 LLDB_LOG(log,
"[{0:x}]:{1:x} ({2:x})", addr, *(
const unsigned long *)src,
1662 *(
unsigned long *)buff);
1672 return PtraceWrapper(PTRACE_GETSIGINFO, tid,
nullptr, siginfo);
1676 unsigned long *message) {
1677 return PtraceWrapper(PTRACE_GETEVENTMSG, tid,
nullptr, message);
1689 assert(thread &&
"thread list should not contain NULL threads");
1690 if (thread->GetID() == thread_id) {
1703 LLDB_LOG(log,
"tid: {0}", thread_id);
1705 auto it = llvm::find_if(
m_threads, [&](
const auto &thread_up) {
1706 return thread_up.get() == &thread;
1727 LLDB_LOG(log,
"Failed to trace a new thread with intel-pt, tid = {0}. {1}",
1728 tid,
error.AsCString());
1737 "Failed to stop a destroyed thread with intel-pt, tid = {0}. {1}",
1738 tid,
error.AsCString());
1745 LLDB_LOG(log,
"pid {0} adding thread with tid {1}",
GetID(), thread_id);
1748 "attempted to add a thread by id that already exists");
1754 m_threads.push_back(std::make_unique<NativeThreadLinux>(*
this, thread_id));
1759 if (tracing_error.
Fail()) {
1776 FileSpec module_file_spec(module_path);
1781 if (it.second.GetFilename() == module_file_spec.
GetFilename()) {
1782 file_spec = it.second;
1786 return Status(
"Module file (%s) not found in /proc/%" PRIu64
"/maps file!",
1799 if (it.second == file) {
1800 load_addr = it.first.GetRange().GetRangeBase();
1804 return Status(
"No load address found for specified file.");
1829 "about to resume tid {0} per explicit request but we have a "
1830 "pending stop notification (tid {1}) that is actively "
1831 "waiting for this thread to stop. Valid sequence of events?",
1839 const auto resume_result = thread.
Resume(signo);
1840 if (resume_result.Success())
1842 return resume_result;
1845 const auto step_result = thread.
SingleStep(signo);
1846 if (step_result.Success())
1851 LLDB_LOG(log,
"Unhandled state {0}.", state);
1852 llvm_unreachable(
"Unhandled state for resume");
1860 LLDB_LOG(log,
"about to process event: (triggering_tid: {0})",
1873 LLDB_LOG(log,
"event processing done");
1880 for (
const auto &thread_sp :
m_threads) {
1893 LLDB_LOG(log,
"pid = {0} remove stepping breakpoint: {1}",
1894 thread_info.first,
error);
1900 SetState(StateType::eStateStopped,
true);
1920 ::pid_t wait_pid = llvm::sys::RetryAfterSignal(
1921 -1, ::waitpid, pid, &status, __WALL | __WNOTHREAD | WNOHANG);
1924 return std::nullopt;
1926 if (wait_pid == -1) {
1928 LLDB_LOG(log,
"waitpid({0}, &status, _) failed: {1}", pid,
1930 return std::nullopt;
1933 assert(wait_pid == pid);
1937 LLDB_LOG(log,
"waitpid({0}) got status = {1}", pid, wait_status);
1946 llvm::DenseMap<lldb::tid_t, WaitStatus> tid_events;
1947 bool checked_main_thread =
false;
1948 for (
const auto &thread_up :
m_threads) {
1949 if (thread_up->GetID() ==
GetID())
1950 checked_main_thread =
true;
1952 if (std::optional<WaitStatus> status =
HandlePid(thread_up->GetID()))
1953 tid_events.try_emplace(thread_up->GetID(), *status);
1957 if (!checked_main_thread) {
1959 tid_events.try_emplace(
GetID(), *status);
1962 for (
auto &KV : tid_events) {
1963 LLDB_LOG(log,
"processing {0}({1}) ...", KV.first, KV.second);
1972 assert(thread &&
"Why did this thread disappear?");
1980 void *data,
size_t data_size,
1992 *(
unsigned int *)addr, data);
1998 error.SetErrorToErrno();
2003 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
2021 if (type ==
"intel-pt") {
2022 if (Expected<TraceIntelPTStartRequest> request =
2023 json::parse<TraceIntelPTStartRequest>(json_request,
2024 "TraceIntelPTStartRequest")) {
2027 return request.takeError();
2034 if (request.
type ==
"intel-pt")
2040 if (type ==
"intel-pt")
2047 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 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()
static std::optional< WaitStatus > HandlePid(::pid_t pid)
#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 Factory::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.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, MainLoop &mainloop) const override
Launch a process for debugging.
Extension GetSupportedExtensions() const override
Get the bitmask of extensions supported by this process plugin.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate, MainLoop &mainloop) const override
Attach to an existing process.
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.
MainLoop::SignalHandleUP m_sigchld_handle
void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index)
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
NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, MainLoop &mainloop, llvm::ArrayRef<::pid_t > tids)
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)
void WaitForCloneNotification(::pid_t pid)
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.
bool Contains(BaseType r) const
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
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.