pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
Info.GetArchitecture(), mainloop));
- status = process_up->ReinitializeThreads();
+ status = process_up->SetupTrace();
if (status.Fail())
return status.ToError();
if (!status.Success())
return status.ToError();
+ status = process_up->SetupTrace();
+ if (status.Fail())
+ return status.ToError();
+
return std::move(process_up);
}
return;
}
assert(info.pl_event == PL_EVENT_SIGNAL);
- // TODO: do we need to handle !PL_FLAG_SI?
- assert(info.pl_flags & PL_FLAG_SI);
- assert(info.pl_siginfo.si_signo == SIGTRAP);
-
- LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, si_code = {2}", pid,
- info.pl_lwpid, info.pl_siginfo.si_code);
+ LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}", pid, info.pl_lwpid);
NativeThreadFreeBSD *thread = nullptr;
+
+ if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) {
+ if (info.pl_flags & PL_FLAG_BORN) {
+ LLDB_LOG(log, "monitoring new thread, tid = {0}", info.pl_lwpid);
+ AddThread(info.pl_lwpid);
+ } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ {
+ LLDB_LOG(log, "thread exited, tid = {0}", info.pl_lwpid);
+ RemoveThread(info.pl_lwpid);
+ }
+
+ Status error =
+ PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+ if (error.Fail())
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+
if (info.pl_lwpid > 0) {
for (const auto &t : m_threads) {
if (t->GetID() == static_cast<lldb::tid_t>(info.pl_lwpid)) {
info.pl_lwpid);
}
- switch (info.pl_siginfo.si_code) {
- case TRAP_BRKPT:
- if (thread) {
- thread->SetStoppedByBreakpoint();
- FixupBreakpointPCAsNeeded(*thread);
+ if (info.pl_flags & PL_FLAG_SI) {
+ assert(info.pl_siginfo.si_signo == SIGTRAP);
+
+ switch (info.pl_siginfo.si_code) {
+ case TRAP_BRKPT:
+ if (thread) {
+ thread->SetStoppedByBreakpoint();
+ FixupBreakpointPCAsNeeded(*thread);
+ }
+ SetState(StateType::eStateStopped, true);
+ break;
+ case TRAP_TRACE:
+ if (thread)
+ thread->SetStoppedByTrace();
+ SetState(StateType::eStateStopped, true);
+ break;
}
- SetState(StateType::eStateStopped, true);
- break;
- case TRAP_TRACE:
- if (thread)
- thread->SetStoppedByTrace();
- SetState(StateType::eStateStopped, true);
- break;
}
}
return buf;
}
+Status NativeProcessFreeBSD::SetupTrace() {
+ // Enable event reporting
+ int events;
+ Status status =
+ PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+ events |= PTRACE_LWP;
+ status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+
+ return ReinitializeThreads();
+}
+
Status NativeProcessFreeBSD::ReinitializeThreads() {
// Clear old threads
m_threads.clear();
Status NativeRegisterContextFreeBSD_x86_64::ReadRegisterSet(uint32_t set) {
switch (set) {
case GPRegSet:
- return DoRegisterSet(PT_GETREGS, &m_gpr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ &m_gpr);
case FPRegSet:
#if defined(__x86_64__)
- return DoRegisterSet(PT_GETFPREGS, &m_fpr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETFPREGS, m_thread.GetID(),
+ &m_fpr);
#else
- return DoRegisterSet(PT_GETXMMREGS, &m_fpr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETXMMREGS, m_thread.GetID(),
+ &m_fpr);
#endif
case DBRegSet:
- return DoRegisterSet(PT_GETDBREGS, &m_dbr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETDBREGS, m_thread.GetID(),
+ &m_dbr);
case XSaveRegSet: {
struct ptrace_xstate_info info;
Status ret = NativeProcessFreeBSD::PtraceWrapper(
Status NativeRegisterContextFreeBSD_x86_64::WriteRegisterSet(uint32_t set) {
switch (set) {
case GPRegSet:
- return DoRegisterSet(PT_SETREGS, &m_gpr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ &m_gpr);
case FPRegSet:
#if defined(__x86_64__)
- return DoRegisterSet(PT_SETFPREGS, &m_fpr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETFPREGS, m_thread.GetID(),
+ &m_fpr);
#else
- return DoRegisterSet(PT_SETXMMREGS, &m_fpr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETXMMREGS, m_thread.GetID(),
+ &m_fpr);
#endif
case DBRegSet:
- return DoRegisterSet(PT_SETDBREGS, &m_dbr);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETDBREGS, m_thread.GetID(),
+ &m_dbr);
case XSaveRegSet:
// ReadRegisterSet() must always be called before WriteRegisterSet().
assert(m_xsave.size() > 0);
m_stop_description() {}
Status NativeThreadFreeBSD::Resume() {
- Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, m_process.GetID(),
- nullptr, GetID());
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID());
if (!ret.Success())
return ret;
- ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, m_process.GetID(),
- nullptr, GetID());
+ ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, GetID());
if (ret.Success())
SetRunning();
return ret;
}
Status NativeThreadFreeBSD::SingleStep() {
- Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, m_process.GetID(),
- nullptr, GetID());
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID());
if (!ret.Success())
return ret;
- ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, m_process.GetID(),
- nullptr, GetID());
+ ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, GetID());
if (ret.Success())
SetStepping();
return ret;
}
Status NativeThreadFreeBSD::Suspend() {
- Status ret = NativeProcessFreeBSD::PtraceWrapper(
- PT_SUSPEND, m_process.GetID(), nullptr, GetID());
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_SUSPEND, GetID());
if (ret.Success())
SetStopped();
return ret;