diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-04-01 11:33:11 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-04-01 11:33:11 +0200 |
commit | c4adc6d6aa772cb9b8e5dc294bbdc75b4e22f38d (patch) | |
tree | 9afe3b10ec514dc5b1b284b4b39bd61f22d4f7f9 | |
parent | 01570ff5ee4568c63d8466cfb972cc31a2451a18 (diff) |
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.cxx | 22 | ||||
-rw-r--r-- | build2/context | 2 | ||||
-rw-r--r-- | build2/scheduler | 2 | ||||
-rw-r--r-- | build2/test/rule.cxx | 11 | ||||
-rw-r--r-- | build2/test/script/builtin.cxx | 12 | ||||
-rw-r--r-- | build2/test/script/parser.cxx | 11 | ||||
-rw-r--r-- | build2/utility | 1 |
7 files changed, 11 insertions, 50 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index c9396ef..ccbbae6 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 95030d8..bc73d5b 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 86a48df..c6f4f7f 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 8e39104..bc90c1f 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 9bd6a1b..a2f3107 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 d6d77fe..350ca44 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 2880bb5..d7b4797 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() |