Serialize exceptions from the sandbox process to the parent
Fixes #4118.
This commit is contained in:
parent
27ca87c46a
commit
be149acfda
|
@ -2737,9 +2737,12 @@ void DerivationGoal::startBuilder()
|
||||||
/* Check if setting up the build environment failed. */
|
/* Check if setting up the build environment failed. */
|
||||||
while (true) {
|
while (true) {
|
||||||
string msg = readLine(builderOut.readSide.get());
|
string msg = readLine(builderOut.readSide.get());
|
||||||
|
if (string(msg, 0, 1) == "\2") break;
|
||||||
if (string(msg, 0, 1) == "\1") {
|
if (string(msg, 0, 1) == "\1") {
|
||||||
if (msg.size() == 1) break;
|
FdSource source(builderOut.readSide.get());
|
||||||
throw Error(string(msg, 1));
|
auto ex = readError(source);
|
||||||
|
ex.addTrace({}, "while setting up the build environment");
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
debug(msg);
|
debug(msg);
|
||||||
}
|
}
|
||||||
|
@ -3785,7 +3788,7 @@ void DerivationGoal::runChild()
|
||||||
args.push_back(rewriteStrings(i, inputRewrites));
|
args.push_back(rewriteStrings(i, inputRewrites));
|
||||||
|
|
||||||
/* Indicate that we managed to set up the build environment. */
|
/* Indicate that we managed to set up the build environment. */
|
||||||
writeFull(STDERR_FILENO, string("\1\n"));
|
writeFull(STDERR_FILENO, string("\2\n"));
|
||||||
|
|
||||||
/* Execute the program. This should not return. */
|
/* Execute the program. This should not return. */
|
||||||
if (drv->isBuiltin()) {
|
if (drv->isBuiltin()) {
|
||||||
|
@ -3815,8 +3818,11 @@ void DerivationGoal::runChild()
|
||||||
|
|
||||||
throw SysError("executing '%1%'", drv->builder);
|
throw SysError("executing '%1%'", drv->builder);
|
||||||
|
|
||||||
} catch (std::exception & e) {
|
} catch (Error & e) {
|
||||||
writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n");
|
writeFull(STDERR_FILENO, "\1\n");
|
||||||
|
FdSink sink(STDERR_FILENO);
|
||||||
|
sink << e;
|
||||||
|
sink.flush();
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,6 +266,24 @@ Sink & operator << (Sink & sink, const StringSet & s)
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sink & operator << (Sink & sink, const Error & ex)
|
||||||
|
{
|
||||||
|
auto info = ex.info();
|
||||||
|
sink
|
||||||
|
<< "Error"
|
||||||
|
<< info.level
|
||||||
|
<< info.name
|
||||||
|
<< info.description
|
||||||
|
<< (info.hint ? info.hint->str() : "")
|
||||||
|
<< 0 // FIXME: info.errPos
|
||||||
|
<< info.traces.size();
|
||||||
|
for (auto & trace : info.traces) {
|
||||||
|
sink << 0; // FIXME: trace.pos
|
||||||
|
sink << trace.hint.str();
|
||||||
|
}
|
||||||
|
return sink;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void readPadding(size_t len, Source & source)
|
void readPadding(size_t len, Source & source)
|
||||||
{
|
{
|
||||||
|
@ -319,6 +337,30 @@ template Paths readStrings(Source & source);
|
||||||
template PathSet readStrings(Source & source);
|
template PathSet readStrings(Source & source);
|
||||||
|
|
||||||
|
|
||||||
|
Error readError(Source & source)
|
||||||
|
{
|
||||||
|
auto type = readString(source);
|
||||||
|
assert(type == "Error");
|
||||||
|
ErrorInfo info;
|
||||||
|
info.level = (Verbosity) readInt(source);
|
||||||
|
info.name = readString(source);
|
||||||
|
info.description = readString(source);
|
||||||
|
auto hint = readString(source);
|
||||||
|
if (hint != "") info.hint = hintformat(std::move(format("%s") % hint));
|
||||||
|
auto havePos = readNum<size_t>(source);
|
||||||
|
assert(havePos == 0);
|
||||||
|
auto nrTraces = readNum<size_t>(source);
|
||||||
|
for (size_t i = 0; i < nrTraces; ++i) {
|
||||||
|
havePos = readNum<size_t>(source);
|
||||||
|
assert(havePos == 0);
|
||||||
|
info.traces.push_back(Trace {
|
||||||
|
.hint = hintformat(std::move(format("%s") % readString(source)))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Error(std::move(info));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void StringSink::operator () (const unsigned char * data, size_t len)
|
void StringSink::operator () (const unsigned char * data, size_t len)
|
||||||
{
|
{
|
||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
|
|
|
@ -321,6 +321,7 @@ inline Sink & operator << (Sink & sink, uint64_t n)
|
||||||
Sink & operator << (Sink & sink, const string & s);
|
Sink & operator << (Sink & sink, const string & s);
|
||||||
Sink & operator << (Sink & sink, const Strings & s);
|
Sink & operator << (Sink & sink, const Strings & s);
|
||||||
Sink & operator << (Sink & sink, const StringSet & s);
|
Sink & operator << (Sink & sink, const StringSet & s);
|
||||||
|
Sink & operator << (Sink & in, const Error & ex);
|
||||||
|
|
||||||
|
|
||||||
MakeError(SerialisationError, Error);
|
MakeError(SerialisationError, Error);
|
||||||
|
@ -382,6 +383,8 @@ Source & operator >> (Source & in, bool & b)
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error readError(Source & source);
|
||||||
|
|
||||||
|
|
||||||
/* An adapter that converts a std::basic_istream into a source. */
|
/* An adapter that converts a std::basic_istream into a source. */
|
||||||
struct StreamToSourceAdapter : Source
|
struct StreamToSourceAdapter : Source
|
||||||
|
|
Loading…
Reference in a new issue