Pull up revision 3becdd597a7f5f996eeceebf06ac7f77aaa7c30c from upstream:

Catch and report unhandled exceptions before they propagate to C land

The C++ interface to run test cases goes like this:

    1) C++ run function -> 2) C run function -> 3) C++ wrapper for
    test case -> 4) test case head/body/cleanup

The previous code caught and reported unhandled exceptions in 1).
However, such approach does not seem to work everywhere.  It fails,
for example, in NetBSD/i386 but works in NetBSD/amd64.  I am not sure
which platform implementation is correct nor if there even _is_ a
defined behavior.  No matter what, it feels wrong and clunky.

Move the last-resort exception catching to happen in 3) so that
exceptions don't propagate back to C.

Fixes the test-programs/result_test:result_exception test case in
NetBSD/i386 5.99.34.
This commit is contained in:
jmmv 2010-07-06 18:03:37 +00:00
parent 99fa704726
commit d59f14065c
1 changed files with 36 additions and 20 deletions

View File

@ -119,27 +119,49 @@ static std::map< const atf_tc_t*, const impl::tc* > cwraps;
void
impl::tc::wrap_head(atf_tc_t *tc)
{
std::map< atf_tc_t*, impl::tc* >::iterator iter = wraps.find(tc);
INV(iter != wraps.end());
(*iter).second->head();
try {
std::map< atf_tc_t*, impl::tc* >::iterator iter = wraps.find(tc);
INV(iter != wraps.end());
(*iter).second->head();
} catch (const std::exception& e) {
std::cerr << "Caught unhandled exception: " + std::string(e.what());
std::abort();
} catch (...) {
std::cerr << "Caught unknown exception";
std::abort();
}
}
void
impl::tc::wrap_body(const atf_tc_t *tc)
{
std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
cwraps.find(tc);
INV(iter != cwraps.end());
(*iter).second->body();
try {
std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
cwraps.find(tc);
INV(iter != cwraps.end());
(*iter).second->body();
} catch (const std::exception& e) {
fail("Caught unhandled exception: " + std::string(e.what()));
} catch (...) {
fail("Caught unknown exception");
}
}
void
impl::tc::wrap_cleanup(const atf_tc_t *tc)
{
std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
cwraps.find(tc);
INV(iter != cwraps.end());
(*iter).second->cleanup();
try {
std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
cwraps.find(tc);
INV(iter != cwraps.end());
(*iter).second->cleanup();
} catch (const std::exception& e) {
std::cerr << "Caught unhandled exception: " + std::string(e.what());
std::abort();
} catch (...) {
std::cerr << "Caught unknown exception";
std::abort();
}
}
impl::tc::tc(const std::string& ident, const bool has_cleanup) :
@ -251,15 +273,9 @@ void
impl::tc::run(const fs::path& resfile)
const
{
try {
atf_error_t err = atf_tc_run(&m_tc, resfile.c_path());
if (atf_is_error(err))
throw_atf_error(err);
} catch (const std::exception& e) {
fail("Caught unhandled exception: " + std::string(e.what()));
} catch (...) {
fail("Caught unknown exception");
}
atf_error_t err = atf_tc_run(&m_tc, resfile.c_path());
if (atf_is_error(err))
throw_atf_error(err);
}
void