18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/Errno.h"
29#if defined(__arm64__) || defined(__aarch64__)
32[[noreturn]]
void Child() {
33 if (ptrace(PTRACE_TRACEME, 0,
nullptr,
nullptr) == -1)
45 for (
volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
58 llvm::sys::RetryAfterSignal(-1, waitpid, pid, &status, __WALL);
62bool WorkaroundNeeded() {
70 if (child_pid == -1) {
77 ChildDeleter child_deleter{child_pid};
78 cpu_set_t available_cpus;
79 if (sched_getaffinity(child_pid,
sizeof available_cpus, &available_cpus) ==
81 LLDB_LOG(log,
"failed to get available cpus: {0}",
87 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, waitpid,
88 child_pid, &status, __WALL);
89 if (wpid != child_pid || !WIFSTOPPED(status)) {
90 LLDB_LOG(log,
"waitpid() failed (status = {0:x}): {1}", status,
96 for (cpu = 0; cpu < CPU_SETSIZE; ++cpu) {
97 if (!CPU_ISSET(cpu, &available_cpus))
103 if (sched_setaffinity(child_pid,
sizeof cpus, &cpus) == -1) {
104 LLDB_LOG(log,
"failed to switch to cpu {0}: {1}", cpu,
117 wpid = llvm::sys::RetryAfterSignal(-1, waitpid,
118 child_pid, &status, __WALL);
119 if (wpid != child_pid || !WIFSTOPPED(status)) {
120 LLDB_LOG(log,
"waitpid() failed (status = {0:x}): {1}", status,
124 if (WSTOPSIG(status) !=
SIGTRAP) {
125 LLDB_LOG(log,
"single stepping on cpu {0} failed with status {1:x}", cpu,
134 "SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING "
135 "LIKELY TO BE UNRELIABLE.");
141 return cpu != CPU_SETSIZE;
149 static bool workaround_needed = WorkaroundNeeded();
150 if (!workaround_needed) {
151 LLDB_LOG(log,
"workaround for thread {0} not needed", tid);
155 cpu_set_t original_set;
156 if (sched_getaffinity(tid,
sizeof original_set, &original_set) != 0) {
158 LLDB_LOG(log,
"Unable to get cpu affinity for thread {0}: {1}", tid,
166 if (sched_setaffinity(tid,
sizeof set, &set) != 0) {
170 LLDB_LOG(log,
"Unable to set cpu affinity for thread {0}: {1}", tid,
174 LLDB_LOG(log,
"workaround for thread {0} prepared", tid);
175 return std::make_unique<SingleStepWorkaround>(tid, original_set);
178SingleStepWorkaround::~SingleStepWorkaround() {
180 LLDB_LOG(log,
"Removing workaround");
181 if (sched_setaffinity(m_tid,
sizeof m_original_set, &m_original_set) != 0) {
182 LLDB_LOG(log,
"Unable to reset cpu affinity for thread {0}: {1}", m_tid,
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
}
static std::unique_ptr< SingleStepWorkaround > Get(::pid_t tid)
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.
@ eErrorTypePOSIX
POSIX error codes.