# # # patch "cmd.cc" # from [1f3f8ffa73ba004b54bce43df573d61e5a55c0e0] # to [2ace2124e73ea6939ee7f4289130b65ce6dfac88] # # patch "monotone.cc" # from [4fcc4fca87bd7f74669d3b6cb4f86645066fdcec] # to [1e9370a6b541ef2ffdd175cde43a60afbab0d276] # # patch "tests/dump_on_crash/__driver__.lua" # from [318446527188e10853add4d6c9b7b82f450f34c8] # to [b98c48bc2d108887b68a90c6e4ff230ae4cab30b] # ============================================================ --- cmd.cc 1f3f8ffa73ba004b54bce43df573d61e5a55c0e0 +++ cmd.cc 2ace2124e73ea6939ee7f4289130b65ce6dfac88 @@ -414,7 +414,7 @@ CMD_HIDDEN(crash, "crash", "", CMD_REF(d } CMD_HIDDEN(crash, "crash", "", CMD_REF(debug), - "{ N | E | I | exception | signal }", + "{ N | E | I | double-throw | exception | signal }", N_("Triggers the specified kind of crash"), "", options::opts::none) @@ -430,6 +430,22 @@ CMD_HIDDEN(crash, "crash", "", CMD_REF(d { I(spoon_exists); } + else if (idx(args,0)() == "double-throw") + { + // This code is rather picky, for example I(false) in the destructor + // won't always work like it should; see http://bugs.debian.org/516862 + class throwing_dtor + { + public: + throwing_dtor() {} + ~throwing_dtor() + { + throw std::exception(); + } + }; + throwing_dtor td; + throw std::exception(); + } #define maybe_throw(ex) if(idx(args,0)()==#ex) throw ex("There is no spoon.") #define maybe_throw_bare(ex) if(idx(args,0)()==#ex) throw ex() else maybe_throw_bare(std::bad_alloc); ============================================================ --- monotone.cc 4fcc4fca87bd7f74669d3b6cb4f86645066fdcec +++ monotone.cc 1e9370a6b541ef2ffdd175cde43a60afbab0d276 @@ -142,6 +142,13 @@ get_usage_str(options::options_type cons return format_usage_strings(names, descriptions, maxnamelen); } +void +mtn_terminate_handler() +{ + ui.fatal(F("std::terminate() - exception thrown while handling another exception")); + exit(3); +} + int cpp_main(int argc, char ** argv) { @@ -154,6 +161,8 @@ cpp_main(int argc, char ** argv) // issue a diagnostic ui_library acquire_ui; + std::set_terminate(&mtn_terminate_handler); + // we want to catch any early informative_failures due to charset // conversion etc try ============================================================ --- tests/dump_on_crash/__driver__.lua 318446527188e10853add4d6c9b7b82f450f34c8 +++ tests/dump_on_crash/__driver__.lua b98c48bc2d108887b68a90c6e4ff230ae4cab30b @@ -15,6 +15,15 @@ check(exists("fork")) check(mtn("crash", "I", "--dump=fork"), 3, false, false) check(exists("fork")) +remove("fork") +check(mtn("crash", "double-throw", "--dump=fork"), 3, false, true) +check(exists("fork")) +-- Make sure we're checking the std::terminate handler, rather than +-- normal exception reporting. Sometimes what should result in +-- std::terminate() will instead result in the second exception +-- being propagated. http://bugs.debian.org/516862 +check(qgrep("std::terminate", "stderr")) + -- all the exceptions caught in monotone.cc and translated to error messages for _,tag in pairs({ 'std::bad_cast', 'std::bad_typeid',