aboutsummaryrefslogtreecommitdiff
path: root/src/libmain
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmain')
-rw-r--r--src/libmain/common-args.cc1
-rw-r--r--src/libmain/common-args.hh1
-rw-r--r--src/libmain/progress-bar.cc2
-rw-r--r--src/libmain/shared.cc1
-rw-r--r--src/libmain/shared.hh20
-rw-r--r--src/libmain/stack.cc12
6 files changed, 33 insertions, 4 deletions
diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc
index 12f5403ea..f92920d18 100644
--- a/src/libmain/common-args.cc
+++ b/src/libmain/common-args.cc
@@ -32,6 +32,7 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
addFlag({
.longName = "option",
.description = "Set the Nix configuration setting *name* to *value* (overriding `nix.conf`).",
+ .category = miscCategory,
.labels = {"name", "value"},
.handler = {[](std::string name, std::string value) {
try {
diff --git a/src/libmain/common-args.hh b/src/libmain/common-args.hh
index 25453b8c6..f180d83ce 100644
--- a/src/libmain/common-args.hh
+++ b/src/libmain/common-args.hh
@@ -6,6 +6,7 @@ namespace nix {
//static constexpr auto commonArgsCategory = "Miscellaneous common options";
static constexpr auto loggingCategory = "Logging-related options";
+static constexpr auto miscCategory = "Miscellaneous global options";
class MixCommonArgs : public virtual Args
{
diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc
index 0bbeaff8d..961f4e18a 100644
--- a/src/libmain/progress-bar.cc
+++ b/src/libmain/progress-bar.cc
@@ -503,7 +503,7 @@ public:
return s[0];
}
- virtual void setPrintBuildLogs(bool printBuildLogs)
+ void setPrintBuildLogs(bool printBuildLogs) override
{
this->printBuildLogs = printBuildLogs;
}
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index c1cf38565..a58428762 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -33,6 +33,7 @@
namespace nix {
+char * * savedArgv;
static bool gcWarning = true;
diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh
index 0cc56d47d..3c37fd627 100644
--- a/src/libmain/shared.hh
+++ b/src/libmain/shared.hh
@@ -113,5 +113,25 @@ struct PrintFreed
/* Install a SIGSEGV handler to detect stack overflows. */
void detectStackOverflow();
+/* Pluggable behavior to run in case of a stack overflow.
+
+ Default value: defaultStackOverflowHandler.
+
+ This is called by the handler installed by detectStackOverflow().
+
+ This gives Nix library consumers a limit opportunity to report the error
+ condition. The handler should exit the process.
+ See defaultStackOverflowHandler() for a reference implementation.
+
+ NOTE: Use with diligence, because this runs in the signal handler, with very
+ limited stack space and a potentially a corrupted heap, all while the failed
+ thread is blocked indefinitely. All functions called must be reentrant. */
+extern std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler;
+
+/* The default, robust implementation of stackOverflowHandler.
+
+ Prints an error message directly to stderr using a syscall instead of the
+ logger. Exits the process immediately after. */
+void defaultStackOverflowHandler(siginfo_t * info, void * ctx);
}
diff --git a/src/libmain/stack.cc b/src/libmain/stack.cc
index b0a4a4c5d..10f71c1dc 100644
--- a/src/libmain/stack.cc
+++ b/src/libmain/stack.cc
@@ -1,4 +1,5 @@
#include "error.hh"
+#include "shared.hh"
#include <cstring>
#include <cstddef>
@@ -29,9 +30,7 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
ptrdiff_t diff = (char *) info->si_addr - sp;
if (diff < 0) diff = -diff;
if (diff < 4096) {
- char msg[] = "error: stack overflow (possible infinite recursion)\n";
- [[gnu::unused]] auto res = write(2, msg, strlen(msg));
- _exit(1); // maybe abort instead?
+ nix::stackOverflowHandler(info, ctx);
}
}
@@ -67,5 +66,12 @@ void detectStackOverflow()
#endif
}
+std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler(defaultStackOverflowHandler);
+
+void defaultStackOverflowHandler(siginfo_t * info, void * ctx) {
+ char msg[] = "error: stack overflow (possible infinite recursion)\n";
+ [[gnu::unused]] auto res = write(2, msg, strlen(msg));
+ _exit(1); // maybe abort instead?
+}
}