summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-01 11:33:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-01 11:33:11 +0200
commitc4adc6d6aa772cb9b8e5dc294bbdc75b4e22f38d (patch)
tree9afe3b10ec514dc5b1b284b4b39bd61f22d4f7f9
parent01570ff5ee4568c63d8466cfb972cc31a2451a18 (diff)
downloadbuild2-c4adc6d6aa772cb9b8e5dc294bbdc75b4e22f38d.tar.gz
build2-c4adc6d6aa772cb9b8e5dc294bbdc75b4e22f38d.tar.xz
build2-c4adc6d6aa772cb9b8e5dc294bbdc75b4e22f38d.zip
Redo handling of unhandled exceptions in async execution
Here is the problem: noexcept looses the call stack. That is, unlike an unhandled exception, if noexcept is tripped, then you won't see the place where it was thrown. In this new implementation we now have noexcept only on the task thunk. And the task is called via a thunk only in case of async execution. This means that if we are executing serially (-j 1), then this will be an unhandled exception, not noexcept. Hopefully will be a bit easier to debug.
-rw-r--r--build2/algorithm.cxx22
-rw-r--r--build2/context2
-rw-r--r--build2/scheduler2
-rw-r--r--build2/test/rule.cxx11
-rw-r--r--build2/test/script/builtin.cxx12
-rw-r--r--build2/test/script/parser.cxx11
-rw-r--r--build2/utility1
7 files changed, 11 insertions, 50 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index c9396ef7..ccbbae60 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -437,7 +437,7 @@ namespace build2
// If step is true then perform only one step of the match/apply sequence.
//
static target_state
- match_impl (action a, target_lock& l, bool step = false) noexcept
+ match_impl (action a, target_lock& l, bool step = false)
{
assert (l.target != nullptr);
target& t (*l.target);
@@ -485,13 +485,6 @@ namespace build2
t.state_ = target_state::failed;
l.offset = target::offset_applied;
}
- catch (const std::exception& e)
- {
- diag_lock l;
- *diag_stream << "unhandled exception: " << e << endl;
- assert (false);
- abort ();
- }
return t.state_;
}
@@ -546,7 +539,7 @@ namespace build2
*task_count,
[a] (target& t,
size_t offset,
- const diag_frame* ds) noexcept
+ const diag_frame* ds)
{
diag_frame df (ds);
phase_lock pl (run_phase::match);
@@ -747,7 +740,7 @@ namespace build2
}
static target_state
- execute_impl (action a, target& t) noexcept
+ execute_impl (action a, target& t)
{
assert (t.task_count.load (memory_order_consume) == target::count_busy ()
&& t.state_ == target_state::unknown);
@@ -788,13 +781,6 @@ namespace build2
{
ts = t.state_ = target_state::failed;
}
- catch (const std::exception& e)
- {
- diag_lock l;
- *diag_stream << "unhandled exception: " << e << endl;
- assert (false);
- abort ();
- }
// Decrement the task count (to count_executed) and wake up any threads
// that might be waiting for this target.
@@ -880,7 +866,7 @@ namespace build2
//
if (sched.async (start_count,
*task_count,
- [a] (target& t, const diag_frame* ds) noexcept
+ [a] (target& t, const diag_frame* ds)
{
diag_frame df (ds);
execute_impl (a, t);
diff --git a/build2/context b/build2/context
index 95030d84..bc73d5b5 100644
--- a/build2/context
+++ b/build2/context
@@ -138,7 +138,7 @@ namespace build2
// for (...)
// {
// sched.async (task_count,
- // [] (...) noexcept
+ // [] (...)
// {
// phase_lock pl (run_phase::match); // (2)
// ...
diff --git a/build2/scheduler b/build2/scheduler
index 86a48df3..c6f4f7fe 100644
--- a/build2/scheduler
+++ b/build2/scheduler
@@ -306,7 +306,7 @@ namespace build2
template <size_t... i>
void
- thunk (std::index_sequence<i...>)
+ thunk (std::index_sequence<i...>) noexcept
{
move (func) (std::get<i> (move (args))...);
}
diff --git a/build2/test/rule.cxx b/build2/test/rule.cxx
index 8e39104b..bc90c1f0 100644
--- a/build2/test/rule.cxx
+++ b/build2/test/rule.cxx
@@ -367,7 +367,7 @@ namespace build2
perform_script_impl (const target& t,
const testscript& ts,
const dir_path& wd,
- const common& c) noexcept
+ const common& c)
{
using namespace script;
@@ -397,13 +397,6 @@ namespace build2
{
r = scope_state::failed;
}
- catch (const std::exception& e)
- {
- diag_lock l;
- *diag_stream << "unhandled exception: " << e << endl;
- assert (false);
- abort ();
- }
return r;
}
@@ -525,7 +518,7 @@ namespace build2
const target& t,
const testscript& ts,
const dir_path& wd,
- const diag_frame* ds) noexcept
+ const diag_frame* ds)
{
diag_frame df (ds);
r = perform_script_impl (t, ts, wd, *this);
diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx
index 9bd6a1bf..a2f3107d 100644
--- a/build2/test/script/builtin.cxx
+++ b/build2/test/script/builtin.cxx
@@ -1355,17 +1355,7 @@ namespace build2
auto_fd in, auto_fd out, auto_fd err,
uint8_t& r) noexcept
{
- try
- {
- r = fn (sp, args, move (in), move (out), move (err));
- }
- catch (const std::exception& e)
- {
- diag_lock l;
- *diag_stream << "unhandled exception: " << e << endl;
- assert (false);
- abort ();
- }
+ r = fn (sp, args, move (in), move (out), move (err));
}
// Run builtin implementation asynchronously.
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index d6d77fee..350ca443 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -2868,7 +2868,7 @@ namespace build2
}
static void
- execute_impl (scope& s, script& scr, runner& r) noexcept
+ execute_impl (scope& s, script& scr, runner& r)
{
try
{
@@ -2879,13 +2879,6 @@ namespace build2
{
s.state = scope_state::failed;
}
- catch (const std::exception& e)
- {
- diag_lock l;
- *diag_stream << "unhandled exception: " << e << endl;
- assert (false);
- abort ();
- }
}
void parser::
@@ -3007,7 +3000,7 @@ namespace build2
[] (scope& s,
script& scr,
runner& r,
- const diag_frame* ds) noexcept
+ const diag_frame* ds)
{
diag_frame df (ds);
execute_impl (s, scr, r);
diff --git a/build2/utility b/build2/utility
index 2880bb5c..d7b4797b 100644
--- a/build2/utility
+++ b/build2/utility
@@ -10,7 +10,6 @@
#include <string> // to_string()
#include <utility> // move(), forward(), declval(), make_pair()
#include <cassert> // assert()
-#include <cstdlib> // abort()
#include <iterator> // make_move_iterator()
#include <algorithm> // *
#include <functional> // ref(), cref()