aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-05-28 12:28:05 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-05-28 16:09:48 +0300
commit52f1e90df5a8c98c5dc9ae3d50f7c24928c7b69b (patch)
tree48e9dbb5b4c4f1fe40ce068ba4005d53cdb9833d
parent1a9e93df517ebcfd836bd94b095c354a4877c96e (diff)
Print backtrace to stderr when terminating due to unhandled exception
-rw-r--r--bdep/bdep.cxx21
-rw-r--r--bdep/buildfile5
2 files changed, 25 insertions, 1 deletions
diff --git a/bdep/bdep.cxx b/bdep/bdep.cxx
index e4146e5..e02687d 100644
--- a/bdep/bdep.cxx
+++ b/bdep/bdep.cxx
@@ -6,8 +6,11 @@
# include <signal.h> // signal()
#endif
-#include <cstring> // strcmp()
+#include <cstring> // strcmp()
#include <iostream>
+#include <exception> // set_terminate(), terminate_handler
+
+#include <libbutl/backtrace.mxx> // backtrace()
#include <bdep/types.hxx>
#include <bdep/utility.hxx>
@@ -152,12 +155,28 @@ init (const common_options& co,
return o;
}
+// Print backtrace if terminating due to an unhandled exception. Note that
+// custom_terminate is non-static and not a lambda to reduce the noise.
+//
+static terminate_handler default_terminate;
+
+void
+custom_terminate ()
+{
+ *diag_stream << backtrace ();
+
+ if (default_terminate != nullptr)
+ default_terminate ();
+}
+
int bdep::
main (int argc, char* argv[])
try
{
using namespace cli;
+ default_terminate = set_terminate (custom_terminate);
+
stderr_term = fdterm (stderr_fd ());
argv0 = argv[0];
diff --git a/bdep/buildfile b/bdep/buildfile
index db38734..702058c 100644
--- a/bdep/buildfile
+++ b/bdep/buildfile
@@ -89,6 +89,11 @@ if ($cxx.class == 'msvc')
elif ($cxx.class == 'gcc')
cxx.coptions += -Wno-unknown-pragmas
+# Make sure backtrace includes function names.
+#
+if ($cxx.target.class == 'linux')
+ cxx.loptions += -rdynamic
+
# Generated options parser.
#
if $cli.configured