aboutsummaryrefslogtreecommitdiff
path: root/bpkg
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-05-28 12:41:31 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-05-28 16:07:02 +0300
commitab9f63449f38a2ee7fe98d2644b303beaa499773 (patch)
treee3a424654fb52a198fa450e2f55f548b24d0534f /bpkg
parent31e8d1a676bb6f41bda08b207b0482ec057dbe45 (diff)
Print backtrace to stderr when terminating due to unhandled exception
Diffstat (limited to 'bpkg')
-rw-r--r--bpkg/bpkg.cxx19
-rw-r--r--bpkg/buildfile5
2 files changed, 24 insertions, 0 deletions
diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx
index 042e4f0..fdcb8bb 100644
--- a/bpkg/bpkg.cxx
+++ b/bpkg/bpkg.cxx
@@ -7,6 +7,9 @@
#endif
#include <iostream>
+#include <exception> // set_terminate(), terminate_handler
+
+#include <libbutl/backtrace.mxx> // backtrace()
#include <bpkg/types.hxx>
#include <bpkg/utility.hxx>
@@ -140,12 +143,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 bpkg::
main (int argc, char* argv[])
try
{
using namespace cli;
+ default_terminate = set_terminate (custom_terminate);
+
stderr_term = fdterm (stderr_fd ());
exec_dir = path (argv[0]).directory ();
diff --git a/bpkg/buildfile b/bpkg/buildfile
index 518b25b..adb6d3b 100644
--- a/bpkg/buildfile
+++ b/bpkg/buildfile
@@ -94,6 +94,11 @@ if ($cxx.id == 'msvc' && $cxx.version.major == 19 && $cxx.version.minor < 10)
obj{utility}: cxx.poptions += -DBPKG_EXE_SUFFIX='"'$bin.exe.suffix'"'
+# Make sure backtrace includes function names.
+#
+if ($cxx.target.class == 'linux')
+ cxx.loptions += -rdynamic
+
# Generated options parser.
#
if $cli.configured