Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nix
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 8a29052cb2f5
Choose a base ref
...
head repository: NixOS/nix
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 906adadacd2d
Choose a head ref
  • 2 commits
  • 10 files changed
  • 1 contributor

Commits on Apr 7, 2021

  1. Copy the full SHA
    9b9e703 View commit details
  2. Restore stack size in child processes

    Fixes #4673.
    edolstra committed Apr 7, 2021
    Copy the full SHA
    906adad View commit details
Showing with 64 additions and 54 deletions.
  1. +2 −2 src/libmain/shared.cc
  2. +2 −2 src/libstore/ssh.cc
  3. +38 −3 src/libutil/util.cc
  4. +9 −3 src/libutil/util.hh
  5. +1 −3 src/nix-build/nix-build.cc
  6. +1 −2 src/nix/develop.cc
  7. +2 −1 src/nix/edit.cc
  8. +1 −12 src/nix/main.cc
  9. +7 −23 src/nix/repl.cc
  10. +1 −3 src/nix/run.cc
4 changes: 2 additions & 2 deletions src/libmain/shared.cc
Original file line number Diff line number Diff line change
@@ -310,7 +310,7 @@ void printVersion(const string & programName)

void showManPage(const string & name)
{
restoreSignals();
restoreProcessContext();
setenv("MANPATH", settings.nixManDir.c_str(), 1);
execlp("man", "man", name.c_str(), nullptr);
throw SysError("command 'man %1%' failed", name.c_str());
@@ -373,7 +373,7 @@ RunPager::RunPager()
throw SysError("dupping stdin");
if (!getenv("LESS"))
setenv("LESS", "FRSXMK", 1);
restoreSignals();
restoreProcessContext();
if (pager)
execl("/bin/sh", "sh", "-c", pager, nullptr);
execlp("pager", "pager", nullptr);
4 changes: 2 additions & 2 deletions src/libstore/ssh.cc
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
options.dieWithParent = false;

conn->sshPid = startProcess([&]() {
restoreSignals();
restoreProcessContext();

close(in.writeSide.get());
close(out.readSide.get());
@@ -110,7 +110,7 @@ Path SSHMaster::startMaster()
options.dieWithParent = false;

state->sshMaster = startProcess([&]() {
restoreSignals();
restoreProcessContext();

close(out.readSide.get());

41 changes: 38 additions & 3 deletions src/libutil/util.cc
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@

#ifdef __linux__
#include <sys/prctl.h>
#include <sys/resource.h>
#endif


@@ -1116,7 +1117,7 @@ void runProgram2(const RunOptions & options)
Strings args_(options.args);
args_.push_front(options.program);

restoreSignals();
restoreProcessContext();

if (options.searchPath)
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
@@ -1612,12 +1613,45 @@ void startSignalHandlerThread()
std::thread(signalHandlerThread, set).detach();
}

void restoreSignals()
static void restoreSignals()
{
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
throw SysError("restoring signals");
}

#if __linux__
rlim_t savedStackSize = 0;
#endif

void setStackSize(size_t stackSize)
{
#if __linux__
struct rlimit limit;
if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) {
savedStackSize = limit.rlim_cur;
limit.rlim_cur = stackSize;
setrlimit(RLIMIT_STACK, &limit);
}
#endif
}

void restoreProcessContext()
{
restoreSignals();

restoreAffinity();

#if __linux__
if (savedStackSize) {
struct rlimit limit;
if (getrlimit(RLIMIT_STACK, &limit) == 0) {
limit.rlim_cur = savedStackSize;
setrlimit(RLIMIT_STACK, &limit);
}
}
#endif
}

/* RAII helper to automatically deregister a callback. */
struct InterruptCallbackImpl : InterruptCallback
{
@@ -1680,10 +1714,11 @@ string showBytes(uint64_t bytes)
}


// FIXME: move to libstore/build
void commonChildInit(Pipe & logPipe)
{
const static string pathNullDevice = "/dev/null";
restoreSignals();
restoreProcessContext();

/* Put the child in a separate session (and thus a separate
process group) so that it has no controlling terminal (meaning
12 changes: 9 additions & 3 deletions src/libutil/util.hh
Original file line number Diff line number Diff line change
@@ -300,6 +300,15 @@ std::pair<int, std::string> runProgram(const RunOptions & options);
void runProgram2(const RunOptions & options);


/* Change the stack size. */
void setStackSize(size_t stackSize);


/* Restore the original inherited Unix process context (such as signal
masks, stack size, CPU affinity). */
void restoreProcessContext();


class ExecError : public Error
{
public:
@@ -513,9 +522,6 @@ class Callback;
on the current thread (and thus any threads created by it). */
void startSignalHandlerThread();

/* Restore default signal handling. */
void restoreSignals();

struct InterruptCallback
{
virtual ~InterruptCallback() { };
4 changes: 1 addition & 3 deletions src/nix-build/nix-build.cc
Original file line number Diff line number Diff line change
@@ -422,8 +422,6 @@ static void main_nix_build(int argc, char * * argv)
} else
env[var.first] = var.second;

restoreAffinity();

/* Run a shell using the derivation's environment. For
convenience, source $stdenv/setup to setup additional
environment variables and shell functions. Also don't
@@ -473,7 +471,7 @@ static void main_nix_build(int argc, char * * argv)

auto argPtrs = stringsToCharPtrs(args);

restoreSignals();
restoreProcessContext();

logger->stop();

3 changes: 1 addition & 2 deletions src/nix/develop.cc
Original file line number Diff line number Diff line change
@@ -462,8 +462,7 @@ struct CmdDevelop : Common, MixEnvironment
auto args = phase || !command.empty() ? Strings{std::string(baseNameOf(shell)), rcFilePath}
: Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};

restoreAffinity();
restoreSignals();
restoreProcessContext();

execvp(shell.c_str(), stringsToCharPtrs(args).data());

3 changes: 2 additions & 1 deletion src/nix/edit.cc
Original file line number Diff line number Diff line change
@@ -42,7 +42,8 @@ struct CmdEdit : InstallableCommand

auto args = editorFor(pos);

restoreSignals();
restoreProcessContext();

execvp(args.front().c_str(), stringsToCharPtrs(args).data());

std::string command;
13 changes: 1 addition & 12 deletions src/nix/main.cc
Original file line number Diff line number Diff line change
@@ -17,10 +17,6 @@
#include <netdb.h>
#include <netinet/in.h>

#if __linux__
#include <sys/resource.h>
#endif

#include <nlohmann/json.hpp>

extern std::string chrootHelperName;
@@ -335,14 +331,7 @@ int main(int argc, char * * argv)
{
// Increase the default stack size for the evaluator and for
// libstdc++'s std::regex.
#if __linux__
rlim_t stackSize = 64 * 1024 * 1024;
struct rlimit limit;
if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) {
limit.rlim_cur = stackSize;
setrlimit(RLIMIT_STACK, &limit);
}
#endif
nix::setStackSize(64 * 1024 * 1024);

return nix::handleExceptions(argv[0], [&]() {
nix::mainWrapped(argc, argv);
30 changes: 7 additions & 23 deletions src/nix/repl.cc
Original file line number Diff line number Diff line change
@@ -343,24 +343,6 @@ StringSet NixRepl::completePrefix(string prefix)
}


static int runProgram(const string & program, const Strings & args)
{
Strings args2(args);
args2.push_front(program);

Pid pid;
pid = fork();
if (pid == -1) throw SysError("forking");
if (pid == 0) {
restoreAffinity();
execvp(program.c_str(), stringsToCharPtrs(args2).data());
_exit(1);
}

return pid.wait();
}


bool isVarName(const string & s)
{
if (s.size() == 0) return false;
@@ -462,7 +444,7 @@ bool NixRepl::processLine(string line)
auto args = editorFor(pos);
auto editor = args.front();
args.pop_front();
runProgram(editor, args);
runProgram(editor, true, args);

// Reload right after exiting the editor
state->resetFileCache();
@@ -481,7 +463,7 @@ bool NixRepl::processLine(string line)
state->callFunction(f, v, result, Pos());

StorePath drvPath = getDerivationPath(result);
runProgram(settings.nixBinDir + "/nix-shell", Strings{state->store->printStorePath(drvPath)});
runProgram(settings.nixBinDir + "/nix-shell", true, {state->store->printStorePath(drvPath)});
}

else if (command == ":b" || command == ":i" || command == ":s") {
@@ -494,16 +476,18 @@ bool NixRepl::processLine(string line)
/* We could do the build in this process using buildPaths(),
but doing it in a child makes it easier to recover from
problems / SIGINT. */
if (runProgram(settings.nixBinDir + "/nix", Strings{"build", "--no-link", drvPathRaw}) == 0) {
try {
runProgram(settings.nixBinDir + "/nix", true, {"build", "--no-link", drvPathRaw});
auto drv = state->store->readDerivation(drvPath);
std::cout << std::endl << "this derivation produced the following outputs:" << std::endl;
for (auto & i : drv.outputsAndOptPaths(*state->store))
std::cout << fmt(" %s -> %s\n", i.first, state->store->printStorePath(*i.second.second));
} catch (ExecError &) {
}
} else if (command == ":i") {
runProgram(settings.nixBinDir + "/nix-env", Strings{"-i", drvPathRaw});
runProgram(settings.nixBinDir + "/nix-env", true, {"-i", drvPathRaw});
} else {
runProgram(settings.nixBinDir + "/nix-shell", Strings{drvPathRaw});
runProgram(settings.nixBinDir + "/nix-shell", true, {drvPathRaw});
}
}

4 changes: 1 addition & 3 deletions src/nix/run.cc
Original file line number Diff line number Diff line change
@@ -31,9 +31,7 @@ struct RunCommon : virtual Command
{
stopProgressBar();

restoreSignals();

restoreAffinity();
restoreProcessContext();

/* If this is a diverted store (i.e. its "logical" location
(typically /nix/store) differs from its "physical" location