Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Headers/DebugServer2/Host/POSIX/PTrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class PTrace {

public:
virtual ErrorCode attach(ProcessId pid);
virtual ErrorCode detach(ProcessId pid);
virtual ErrorCode detach(ProcessId pid, int signal = 0);

public:
virtual ErrorCode kill(ProcessThreadId const &ptid, int signal) = 0;
Expand Down
2 changes: 1 addition & 1 deletion Headers/DebugServer2/Target/POSIX/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Process : public ds2::Target::ProcessBase {
bool checkInterrupt(ThreadId tid, int waitStatus);

public:
ErrorCode detach() override;
ErrorCode detach(bool stopped) override;
ErrorCode interrupt() override;
ErrorCode terminate() override;
bool isAlive() const override;
Expand Down
2 changes: 1 addition & 1 deletion Headers/DebugServer2/Target/ProcessBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class ProcessBase {
virtual void cleanup();

public:
virtual ErrorCode detach() = 0;
virtual ErrorCode detach(bool stopped) = 0;

public:
virtual ErrorCode suspend();
Expand Down
2 changes: 1 addition & 1 deletion Headers/DebugServer2/Target/Windows/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Process : public ds2::Target::ProcessBase,
ErrorCode writeDebugBreakCode(uint64_t address);

public:
ErrorCode detach() override;
ErrorCode detach(bool stopped) override;
ErrorCode interrupt() override;
ErrorCode terminate() override;
bool isAlive() const override;
Expand Down
2 changes: 1 addition & 1 deletion Sources/GDBRemote/DebugSessionImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ ErrorCode DebugSessionImplBase::onDetach(Session &, ProcessId pid,
CHK(_process->suspend());
}

return _process->detach();
return _process->detach(stopped);
}

ErrorCode DebugSessionImplBase::onTerminate(Session &session,
Expand Down
7 changes: 4 additions & 3 deletions Sources/Host/POSIX/PTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,14 @@ ErrorCode PTrace::attach(ProcessId pid) {
return kSuccess;
}

ErrorCode PTrace::detach(ProcessId pid) {
ErrorCode PTrace::detach(ProcessId pid, int signal) {
if (pid <= kAnyProcessId)
return kErrorProcessNotFound;

DS2LOG(Debug, "detaching from pid %" PRIu64, (uint64_t)pid);
DS2LOG(Debug, "detaching from pid %" PRIu64 " with signal %d", (uint64_t)pid,
signal);

if (wrapPtrace(PTCMD(DETACH), pid, nullptr, nullptr) < 0)
if (wrapPtrace(PTCMD(DETACH), pid, nullptr, signal) < 0)
return Platform::TranslateError();

return kSuccess;
Expand Down
28 changes: 26 additions & 2 deletions Sources/Target/POSIX/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <csignal>
#include <cstring>
#include <memory>
#include <vector>

#include <sys/mman.h>
#include <sys/wait.h>
Expand Down Expand Up @@ -50,10 +51,33 @@ ErrorCode Process::initialize(ProcessId pid, uint32_t flags) {
return kSuccess;
}

ErrorCode Process::detach() {
ErrorCode Process::detach(bool stopped) {
prepareForDetach();

CHK(ptrace().detach(_pid));
// PTRACE_DETACH resumes the tracee as it stops being traced, so a plain
// detach with no signal leaves it running. When the caller wants the
// target left stopped (LLDB's GDB-remote D1 detach-and-stay-stopped
// mode), SIGSTOP has to be delivered as part of the detach itself rather
// than relied on as a side effect of an earlier suspend, since suspending
// a thread beforehand only leaves a signal pending and does not by
// itself survive detaching.
int const signal = stopped ? SIGSTOP : 0;

// ptrace() traces each thread of a multithreaded process as its own
// tracee. Threads created after the initial attach show up via
// PTRACE_EVENT_CLONE rather than a fresh PTRACE_ATTACH, but they still
// need their own PTRACE_DETACH. Detaching only the main pid would leave
// every other thread parked in its last ptrace-stop forever, so this
// best-effort detaches the rest of the threads first.
std::vector<ThreadId> tids;
getThreadIds(tids);
for (ThreadId tid : tids) {
if (tid != _pid) {
ptrace().detach(tid, signal);
}
}

CHK(ptrace().detach(_pid, signal));

cleanup();
_flags &= ~kFlagAttachedProcess;
Expand Down
9 changes: 7 additions & 2 deletions Sources/Target/Windows/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Process::~Process() {
// exit, so we detach at this point. This is required because otherwise the
// debugged winphone process might stay alive in an unclosable state. If
// detached, the winphone process dies gracefully.
detach();
detach(false);
::CloseHandle(_handle);
}

Expand Down Expand Up @@ -125,9 +125,14 @@ Target::Process *Process::Attach(ProcessId pid) {
return process.release();
}

ErrorCode Process::detach() {
ErrorCode Process::detach(bool stopped) {
prepareForDetach();

// DebugActiveProcessStop has no equivalent of POSIX's detach-and-leave-
// stopped: the debuggee always resumes once debugging is stopped, so
// there is nothing here to do differently when stopped is requested.
(void)stopped;

BOOL result = DebugActiveProcessStop(_pid);
if (!result) {
return Platform::TranslateError();
Expand Down
Loading