aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-08-07 08:27:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-08-07 08:27:11 +0200
commit7e3092b83516e720ef367e8172421266078ee7e6 (patch)
treed148680100da8dc9ae9a634bce9a82364825b20e
parent20ce40e34faf6b08f8c3bb9a149a3975fd4403cc (diff)
Improve deadlock diagnostics (suppress stack trace, reword)
-rw-r--r--build2/b.cxx14
-rw-r--r--libbuild2/function.test.cxx2
-rw-r--r--libbuild2/scheduler.cxx9
-rw-r--r--libbuild2/test/script/parser.test.cxx2
-rw-r--r--libbuild2/utility.cxx9
-rw-r--r--libbuild2/utility.hxx8
-rw-r--r--tests/libbuild2/driver.cxx2
7 files changed, 32 insertions, 14 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 2bb5920..8965d64 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -16,7 +16,7 @@
#include <cstring> // strcmp(), strchr()
#include <typeinfo>
#include <iostream> // cout
-#include <exception> // set_terminate(), terminate_handler
+#include <exception> // terminate(), set_terminate(), terminate_handler
#include <libbutl/pager.mxx>
#include <libbutl/fdstream.mxx> // stderr_fd(), fdterm()
@@ -152,6 +152,15 @@ custom_terminate ()
default_terminate ();
}
+static void
+terminate (bool trace)
+{
+ if (!trace)
+ set_terminate (default_terminate);
+
+ std::terminate ();
+}
+
int build2::
main (int argc, char* argv[])
{
@@ -412,7 +421,8 @@ main (int argc, char* argv[])
// Initialize the global state.
//
- init (argv[0],
+ init (&::terminate,
+ argv[0],
!ops.serial_stop (), ops.dry_run (),
(ops.mtime_check () ? optional<bool> (true) :
ops.no_mtime_check () ? optional<bool> (false) : nullopt),
diff --git a/libbuild2/function.test.cxx b/libbuild2/function.test.cxx
index 5e442a3..a9326f4 100644
--- a/libbuild2/function.test.cxx
+++ b/libbuild2/function.test.cxx
@@ -39,7 +39,7 @@ namespace build2
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (argv[0]);
+ init (nullptr, argv[0]);
reset (strings ()); // No command line variables.
function_family f ("dummy");
diff --git a/libbuild2/scheduler.cxx b/libbuild2/scheduler.cxx
index b261a82..37220c7 100644
--- a/libbuild2/scheduler.cxx
+++ b/libbuild2/scheduler.cxx
@@ -20,7 +20,6 @@
#endif
#include <cerrno>
-#include <exception> // std::terminate()
#include <libbuild2/diagnostics.hxx>
@@ -861,12 +860,12 @@ namespace build2
// thing about abort is if this is not a dependency cycle, then we
// have a core to examine).
//
- error << "detected deadlock that could be caused by a dependency "
- << "cycle" <<
+ error << "deadlock detected, aborting" <<
+ info << "deadlocks are normally caused by dependency cycles" <<
info << "re-run with -s to diagnose dependency cycles" <<
- info << "if not a dependency cycle, please report";
+ info << "if not a dependency cycle, please report as a bug";
- std::terminate ();
+ terminate (false /* trace */);
}
}
}
diff --git a/libbuild2/test/script/parser.test.cxx b/libbuild2/test/script/parser.test.cxx
index 8702e18..ab1f295 100644
--- a/libbuild2/test/script/parser.test.cxx
+++ b/libbuild2/test/script/parser.test.cxx
@@ -154,7 +154,7 @@ namespace build2
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (argv[0]);
+ init (nullptr, argv[0]);
sched.startup (1); // Serial execution.
reset (strings ()); // No command line variables.
diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx
index 396ce82..506e88e 100644
--- a/libbuild2/utility.cxx
+++ b/libbuild2/utility.cxx
@@ -69,6 +69,8 @@ namespace build2
//
// <libbuild2/utility.hxx>
//
+ void (*terminate) (bool);
+
process_path argv0;
const standard_version build_version (LIBBUILD2_VERSION_STR);
@@ -486,12 +488,13 @@ namespace build2
}
void
- init (const char* a0,
+ init (void (*t) (bool),
+ const char* a0,
bool kg, bool dr, optional<bool> mc,
optional<path> cs, optional<path> cg)
{
- // Build system driver process path.
- //
+ terminate = t;
+
argv0 = process::path_search (a0, true);
keep_going = kg;
diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx
index 9598208..c251b64 100644
--- a/libbuild2/utility.hxx
+++ b/libbuild2/utility.hxx
@@ -119,13 +119,19 @@ namespace build2
// Default values are for unit tests.
//
LIBBUILD2_SYMEXPORT void
- init (const char* argv0,
+ init (void (*terminate) (bool),
+ const char* argv0,
bool keep_going = false,
bool dry_run = false,
optional<bool> mtime_check = nullopt,
optional<path> config_sub = nullopt,
optional<path> config_guess = nullopt);
+ // Terminate function. If trace is false, then printing of the stack trace,
+ // if any, should be omitted.
+ //
+ LIBBUILD2_SYMEXPORT extern void (*terminate) (bool trace);
+
// Build system driver process path (argv0.initial is argv[0]).
//
LIBBUILD2_SYMEXPORT extern process_path argv0;
diff --git a/tests/libbuild2/driver.cxx b/tests/libbuild2/driver.cxx
index 20c0ec2..706d276 100644
--- a/tests/libbuild2/driver.cxx
+++ b/tests/libbuild2/driver.cxx
@@ -20,7 +20,7 @@ main (int, char* argv[])
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (argv[0]);
+ init (nullptr, argv[0]);
bash::build2_bash_load ();
in::build2_in_load ();