Skip to content

Commit 78743d5

Browse files
authored
[posix] remove setgid(2)/setsid(2) from ProcessSpawner (#146)
## Purpose Remove the call to `setsid(2)` on every process spawn and make debug inferior process setup items specific to `DebugSession` launched process. This PR makes ds2 process launch behavior consistent with lldb-server. Addresses issue #137 along with PR #143. ## Overview * Eliminate the call to `setsid(2)` from `ProcessSpawner` * Call `setpgid(2)` from the `preExecAction` callback for `DebugSession` process launch. Do not make this call for generic process launch (which again matches `lldb-server`'s behavior). * Move the call to `setgid(2)` from the `ProcessSpawner` implementation into the `preExecAction` callback for `DebugSession` process launch. This move avoids making the call when launching processes that are not debug targets. ## Background It is unclear why there was a call to `setsid(2)` on every process spawn. The implementation of `lldb-server` does not do this. When launching a new gdb server instance of ds2 via the `qLaunchGDBServer`, it always passes along the `--setsid` argument so spawned gdb servers already call `setsid(2)`. When spawning other processes, including debug inferiors, there is no need to make this call; doing so can cause some test failures/hangs due to undelivered signals because the inferior is in a different session. ## Validation Once this PR and #143 are merged, most of the TestGdbRemote* and TestLldbGdbServer* lldb tests succeed with ds2 running on Android and Linux and can be enabled in CI. They do not all pass with this PR alone.
1 parent 7a03bbc commit 78743d5

File tree

2 files changed

+66
-62
lines changed

2 files changed

+66
-62
lines changed

Sources/Host/POSIX/ProcessSpawner.cpp

Lines changed: 58 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -415,79 +415,75 @@ ErrorCode ProcessSpawner::run(std::function<bool()> preExecAction) {
415415
}
416416

417417
if (_pid == 0) {
418-
if (::setgid(::getgid()) == 0) {
419-
::setsid();
420-
421-
for (size_t n = 0; n < 3; n++) {
422-
switch (_descriptors[n].mode) {
423-
case kRedirectConsole:
424-
// do nothing
425-
break;
418+
for (size_t n = 0; n < 3; n++) {
419+
switch (_descriptors[n].mode) {
420+
case kRedirectConsole:
421+
// do nothing
422+
break;
426423

427-
case kRedirectDelegate:
428-
case kRedirectTerminal:
429-
//
430-
// We are using the same virtual terminal for all delegate
431-
// redirections, so dup2() only, do not close. We will close when all
432-
// FDs have been dup2()'d.
433-
//
434-
::dup2(fds[n][WR], n);
435-
break;
424+
case kRedirectDelegate:
425+
case kRedirectTerminal:
426+
//
427+
// We are using the same virtual terminal for all delegate
428+
// redirections, so dup2() only, do not close. We will close when all
429+
// FDs have been dup2()'d.
430+
//
431+
::dup2(fds[n][WR], n);
432+
break;
436433

437-
default:
438-
if (n == 0) {
439-
if (fds[n][WR] != -1) {
440-
::close(fds[n][WR]);
441-
}
442-
::dup2(fds[n][RD], n);
443-
::close(fds[n][RD]);
444-
} else {
445-
if (fds[n][RD] != -1) {
446-
::close(fds[n][RD]);
447-
}
448-
::dup2(fds[n][WR], n);
434+
default:
435+
if (n == 0) {
436+
if (fds[n][WR] != -1) {
449437
::close(fds[n][WR]);
450438
}
451-
break;
439+
::dup2(fds[n][RD], n);
440+
::close(fds[n][RD]);
441+
} else {
442+
if (fds[n][RD] != -1) {
443+
::close(fds[n][RD]);
444+
}
445+
::dup2(fds[n][WR], n);
446+
::close(fds[n][WR]);
452447
}
448+
break;
453449
}
450+
}
454451

455-
close_terminal(term);
452+
close_terminal(term);
456453

457-
if (!_workingDirectory.empty()) {
458-
int res = ::chdir(_workingDirectory.c_str());
459-
if (res != 0) {
460-
return Platform::TranslateError();
461-
}
454+
if (!_workingDirectory.empty()) {
455+
int res = ::chdir(_workingDirectory.c_str());
456+
if (res != 0) {
457+
return Platform::TranslateError();
462458
}
459+
}
463460

464-
std::vector<char *> args;
465-
args.push_back(const_cast<char *>(_executablePath.c_str()));
466-
for (auto const &e : _arguments)
467-
args.push_back(const_cast<char *>(e.c_str()));
468-
args.push_back(nullptr);
469-
470-
std::vector<char *> environment;
471-
for (auto const &env : _environment)
472-
environment.push_back(const_cast<char *>(
473-
(new std::string(env.first + '=' + env.second))->c_str()));
474-
environment.push_back(nullptr);
475-
476-
if (!preExecAction()) {
477-
DS2LOG(Error, "pre exec action failed");
478-
return kErrorUnknown;
479-
}
461+
std::vector<char *> args;
462+
args.push_back(const_cast<char *>(_executablePath.c_str()));
463+
for (auto const &e : _arguments)
464+
args.push_back(const_cast<char *>(e.c_str()));
465+
args.push_back(nullptr);
466+
467+
std::vector<char *> environment;
468+
for (auto const &env : _environment)
469+
environment.push_back(const_cast<char *>(
470+
(new std::string(env.first + '=' + env.second))->c_str()));
471+
environment.push_back(nullptr);
472+
473+
if (!preExecAction()) {
474+
DS2LOG(Error, "pre exec action failed");
475+
return kErrorUnknown;
476+
}
480477

481-
if (_shell) {
482-
if (::execvp(_executablePath.c_str(), &args[0]) < 0) {
483-
DS2LOG(Error, "cannot run shell command %s, error=%s",
484-
_executablePath.c_str(), strerror(errno));
485-
}
486-
} else {
487-
if (::execve(_executablePath.c_str(), &args[0], &environment[0]) < 0) {
488-
DS2LOG(Error, "cannot spawn executable %s, error=%s",
489-
_executablePath.c_str(), strerror(errno));
490-
}
478+
if (_shell) {
479+
if (::execvp(_executablePath.c_str(), &args[0]) < 0) {
480+
DS2LOG(Error, "cannot run shell command %s, error=%s",
481+
_executablePath.c_str(), strerror(errno));
482+
}
483+
} else {
484+
if (::execve(_executablePath.c_str(), &args[0], &environment[0]) < 0) {
485+
DS2LOG(Error, "cannot spawn executable %s, error=%s",
486+
_executablePath.c_str(), strerror(errno));
491487
}
492488
}
493489
::_exit(127);

Sources/Target/POSIX/Process.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@ ds2::Target::Process *Process::Create(ProcessSpawner &spawner) {
148148
auto process = ds2::make_unique<Target::Process>();
149149

150150
if (spawner.run([&process]() {
151+
// move debug targets to their own process group
152+
if (::setpgid(0, 0) != 0)
153+
return false;
154+
155+
// drop the setgid ability of debug targets
156+
if (::setgid(::getgid()) != 0)
157+
return false;
158+
151159
return process->ptrace().traceMe(true) == kSuccess;
152160
}) != kSuccess) {
153161
return nullptr;

0 commit comments

Comments
 (0)