forked from lix-project/lix
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
a323b7826c
|
@ -1,12 +1,11 @@
|
||||||
#!/usr/bin/env nix-shell
|
#!/usr/bin/env nix-shell
|
||||||
#!nix-shell -i python3 -p python3 --pure
|
#!nix-shell -i python3 -p python3 --pure
|
||||||
|
|
||||||
# To be used with `--trace-function-calls` and `-vvvv` and
|
# To be used with `--trace-function-calls` and `flamegraph.pl`.
|
||||||
# `flamegraph.pl`.
|
|
||||||
#
|
#
|
||||||
# For example:
|
# For example:
|
||||||
#
|
#
|
||||||
# nix-instantiate --trace-function-calls -vvvv '<nixpkgs>' -A hello 2> nix-function-calls.trace
|
# nix-instantiate --trace-function-calls '<nixpkgs>' -A hello 2> nix-function-calls.trace
|
||||||
# ./contrib/stack-collapse.py nix-function-calls.trace > nix-function-calls.folded
|
# ./contrib/stack-collapse.py nix-function-calls.trace > nix-function-calls.folded
|
||||||
# nix-shell -p flamegraph --run "flamegraph.pl nix-function-calls.folded > nix-function-calls.svg"
|
# nix-shell -p flamegraph --run "flamegraph.pl nix-function-calls.folded > nix-function-calls.svg"
|
||||||
|
|
||||||
|
|
|
@ -1605,12 +1605,18 @@ stdenv.mkDerivation (rec {
|
||||||
<term><function>builtins.tryEval</function>
|
<term><function>builtins.tryEval</function>
|
||||||
<replaceable>e</replaceable></term>
|
<replaceable>e</replaceable></term>
|
||||||
|
|
||||||
<listitem><para>Try to evaluate <replaceable>e</replaceable>.
|
<listitem><para>Try to shallowly evaluate <replaceable>e</replaceable>.
|
||||||
Return a set containing the attributes <literal>success</literal>
|
Return a set containing the attributes <literal>success</literal>
|
||||||
(<literal>true</literal> if <replaceable>e</replaceable> evaluated
|
(<literal>true</literal> if <replaceable>e</replaceable> evaluated
|
||||||
successfully, <literal>false</literal> if an error was thrown) and
|
successfully, <literal>false</literal> if an error was thrown) and
|
||||||
<literal>value</literal>, equalling <replaceable>e</replaceable>
|
<literal>value</literal>, equalling <replaceable>e</replaceable>
|
||||||
if successful and <literal>false</literal> otherwise.
|
if successful and <literal>false</literal> otherwise. Note that this
|
||||||
|
doesn't evaluate <replaceable>e</replaceable> deeply, so
|
||||||
|
<literal>let e = { x = throw ""; }; in (builtins.tryEval e).success
|
||||||
|
</literal> will be <literal>true</literal>. Using <literal>builtins.deepSeq
|
||||||
|
</literal> one can get the expected result: <literal>let e = { x = throw "";
|
||||||
|
}; in (builtins.tryEval (builtins.deepSeq e e)).success</literal> will be
|
||||||
|
<literal>false</literal>.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -52,12 +52,13 @@ garbage collector as follows:
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-store --gc</screen>
|
$ nix-store --gc</screen>
|
||||||
|
|
||||||
The behaviour of the gargage collector is affected by the <literal>keep-
|
The behaviour of the gargage collector is affected by the
|
||||||
derivations</literal> (default: true) and <literal>keep-outputs</literal>
|
<literal>keep-derivations</literal> (default: true) and <literal>keep-outputs</literal>
|
||||||
(default: false) options in the Nix configuration file. The defaults will ensure
|
(default: false) options in the Nix configuration file. The defaults will ensure
|
||||||
that all derivations that are not build-time dependencies of garbage collector roots
|
that all derivations that are build-time dependencies of garbage collector roots
|
||||||
will be collected but that all output paths that are not runtime dependencies
|
will be kept and that all output paths that are runtime dependencies
|
||||||
will be collected. (This is usually what you want, but while you are developing
|
will be kept as well. All other derivations or paths will be collected.
|
||||||
|
(This is usually what you want, but while you are developing
|
||||||
it may make sense to keep outputs to ensure that rebuild times are quick.)
|
it may make sense to keep outputs to ensure that rebuild times are quick.)
|
||||||
|
|
||||||
If you are feeling uncertain, you can also first view what files would
|
If you are feeling uncertain, you can also first view what files would
|
||||||
|
|
|
@ -12,13 +12,13 @@ struct FunctionCallTrace
|
||||||
FunctionCallTrace(const Pos & pos) : pos(pos) {
|
FunctionCallTrace(const Pos & pos) : pos(pos) {
|
||||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||||
vomit("function-trace entered %1% at %2%", pos, ns.count());
|
printMsg(lvlInfo, "function-trace entered %1% at %2%", pos, ns.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
~FunctionCallTrace() {
|
~FunctionCallTrace() {
|
||||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
|
||||||
vomit("function-trace exited %1% at %2%", pos, ns.count());
|
printMsg(lvlInfo, "function-trace exited %1% at %2%", pos, ns.count());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2364,7 +2364,7 @@ void DerivationGoal::startBuilder()
|
||||||
child = clone(childEntry, stack + stackSize, flags, this);
|
child = clone(childEntry, stack + stackSize, flags, this);
|
||||||
}
|
}
|
||||||
if (child == -1 && (errno == EPERM || errno == EINVAL)) {
|
if (child == -1 && (errno == EPERM || errno == EINVAL)) {
|
||||||
/* Some distros patch Linux to not allow unpriveleged
|
/* Some distros patch Linux to not allow unprivileged
|
||||||
* user namespaces. If we get EPERM or EINVAL, try
|
* user namespaces. If we get EPERM or EINVAL, try
|
||||||
* without CLONE_NEWUSER and see if that works.
|
* without CLONE_NEWUSER and see if that works.
|
||||||
*/
|
*/
|
||||||
|
@ -2410,8 +2410,7 @@ void DerivationGoal::startBuilder()
|
||||||
writeFile("/proc/" + std::to_string(pid) + "/gid_map",
|
writeFile("/proc/" + std::to_string(pid) + "/gid_map",
|
||||||
(format("%d %d 1") % sandboxGid % hostGid).str());
|
(format("%d %d 1") % sandboxGid % hostGid).str());
|
||||||
|
|
||||||
/* Signal the builder that we've updated its user
|
/* Signal the builder that we've updated its user namespace. */
|
||||||
namespace. */
|
|
||||||
writeFull(userNamespaceSync.writeSide.get(), "1");
|
writeFull(userNamespaceSync.writeSide.get(), "1");
|
||||||
userNamespaceSync.writeSide = -1;
|
userNamespaceSync.writeSide = -1;
|
||||||
|
|
||||||
|
|
|
@ -783,7 +783,11 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
assertStorePath(i);
|
assertStorePath(i);
|
||||||
tryToDelete(state, i);
|
tryToDelete(state, i);
|
||||||
if (state.dead.find(i) == state.dead.end())
|
if (state.dead.find(i) == state.dead.end())
|
||||||
throw Error(format("cannot delete path '%1%' since it is still alive") % i);
|
throw Error(format(
|
||||||
|
"cannot delete path '%1%' since it is still alive. "
|
||||||
|
"To find out why use: "
|
||||||
|
"nix-store --query --roots"
|
||||||
|
) % i);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (options.maxFreed > 0) {
|
} else if (options.maxFreed > 0) {
|
||||||
|
|
|
@ -198,6 +198,7 @@ void RemoteStore::setOptions(Connection & conn)
|
||||||
overrides.erase(settings.maxSilentTime.name);
|
overrides.erase(settings.maxSilentTime.name);
|
||||||
overrides.erase(settings.buildCores.name);
|
overrides.erase(settings.buildCores.name);
|
||||||
overrides.erase(settings.useSubstitutes.name);
|
overrides.erase(settings.useSubstitutes.name);
|
||||||
|
overrides.erase(settings.showTrace.name);
|
||||||
conn.to << overrides.size();
|
conn.to << overrides.size();
|
||||||
for (auto & i : overrides)
|
for (auto & i : overrides)
|
||||||
conn.to << i.first << i.second.value;
|
conn.to << i.first << i.second.value;
|
||||||
|
@ -228,7 +229,7 @@ struct ConnectionHandle
|
||||||
|
|
||||||
~ConnectionHandle()
|
~ConnectionHandle()
|
||||||
{
|
{
|
||||||
if (!daemonException && std::uncaught_exceptions()) {
|
if (!daemonException && std::uncaught_exception()) {
|
||||||
handle.markBad();
|
handle.markBad();
|
||||||
debug("closing daemon connection because of an exception");
|
debug("closing daemon connection because of an exception");
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ public:
|
||||||
|
|
||||||
~JSONPlaceholder()
|
~JSONPlaceholder()
|
||||||
{
|
{
|
||||||
assert(!first || std::uncaught_exceptions());
|
assert(!first || std::uncaught_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ void _interrupted()
|
||||||
/* Block user interrupts while an exception is being handled.
|
/* Block user interrupts while an exception is being handled.
|
||||||
Throwing an exception while another exception is being handled
|
Throwing an exception while another exception is being handled
|
||||||
kills the program! */
|
kills the program! */
|
||||||
if (!interruptThrown && !std::uncaught_exceptions()) {
|
if (!interruptThrown && !std::uncaught_exception()) {
|
||||||
interruptThrown = true;
|
interruptThrown = true;
|
||||||
throw Interrupted("interrupted by the user");
|
throw Interrupted("interrupted by the user");
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,12 +282,12 @@ static void _main(int argc, char * * argv)
|
||||||
absolute = canonPath(absPath(i), true);
|
absolute = canonPath(absPath(i), true);
|
||||||
} catch (Error & e) {};
|
} catch (Error & e) {};
|
||||||
if (store->isStorePath(absolute) && std::regex_match(absolute, std::regex(".*\\.drv(!.*)?")))
|
if (store->isStorePath(absolute) && std::regex_match(absolute, std::regex(".*\\.drv(!.*)?")))
|
||||||
drvs.push_back(DrvInfo(*state, store, absolute));
|
drvs.push_back(DrvInfo(*state, store, absolute));
|
||||||
else
|
else
|
||||||
/* If we're in a #! script, interpret filenames
|
/* If we're in a #! script, interpret filenames
|
||||||
relative to the script. */
|
relative to the script. */
|
||||||
exprs.push_back(state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state,
|
exprs.push_back(state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state,
|
||||||
inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i)))));
|
inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i)))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ expect_trace() {
|
||||||
actual=$(
|
actual=$(
|
||||||
nix-instantiate \
|
nix-instantiate \
|
||||||
--trace-function-calls \
|
--trace-function-calls \
|
||||||
-vvvv \
|
|
||||||
--expr "$expr" 2>&1 \
|
--expr "$expr" 2>&1 \
|
||||||
| grep "function-trace" \
|
| grep "function-trace" \
|
||||||
| sed -e 's/ [0-9]*$//'
|
| sed -e 's/ [0-9]*$//'
|
||||||
|
|
Loading…
Reference in a new issue