From ed0d28374e5c4807f7375c39c032a1dc4b5cf874 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 9 Feb 2014 23:34:24 +0000 Subject: [PATCH] Various OOM fixes; fancy terminate() handler. --- ChangeLog | 3 +++ src/lib/job.cc | 26 ++++++++++++++++---------- src/lib/log.cc | 5 +++++ src/lib/util.cc | 30 +++++++++++++++++++++++++++++- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d3633cbd..0a6f52959 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2014-02-09 Carl Hetherington + * Build with a more careful version of libopenjpeg that handles + out-of-memory conditions slightly better. + * Possibly fix repeated no route to host errors in some cases. * Some small bits of increased low-memory stability. diff --git a/src/lib/job.cc b/src/lib/job.cc index 9981934ec..66fa3755d 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -68,9 +68,6 @@ Job::run_wrapper () } catch (libdcp::FileError& e) { - set_progress (1); - set_state (FINISHED_ERROR); - string m = String::compose (_("An error occurred whilst handling the file %1."), boost::filesystem::path (e.filename()).leaf()); try { @@ -84,39 +81,48 @@ Job::run_wrapper () } set_error (e.what(), m); - - } catch (OpenFileError& e) { - set_progress (1); set_state (FINISHED_ERROR); + + } catch (OpenFileError& e) { set_error ( String::compose (_("Could not open %1"), e.file().string()), String::compose (_("DCP-o-matic could not open the file %1. Perhaps it does not exist or is in an unexpected format."), e.file().string()) ); + set_progress (1); + set_state (FINISHED_ERROR); + } catch (boost::thread_interrupted &) { set_state (FINISHED_CANCELLED); - - } catch (std::exception& e) { + } catch (std::bad_alloc& e) { + + set_error (_("Out of memory"), _("There was not enough memory to do this.")); set_progress (1); set_state (FINISHED_ERROR); + + } catch (std::exception& e) { + set_error ( e.what (), _("It is not known what caused this error. The best idea is to report the problem to the DCP-o-matic mailing list (carl@dcpomatic.com)") ); - } catch (...) { - set_progress (1); set_state (FINISHED_ERROR); + + } catch (...) { + set_error ( _("Unknown error"), _("It is not known what caused this error. The best idea is to report the problem to the DCP-o-matic mailing list (carl@dcpomatic.com)") ); + set_progress (1); + set_state (FINISHED_ERROR); } } diff --git a/src/lib/log.cc b/src/lib/log.cc index 9ddf460d4..e79f0e201 100644 --- a/src/lib/log.cc +++ b/src/lib/log.cc @@ -104,6 +104,11 @@ void FileLog::do_log (string m) { FILE* f = fopen_boost (_file, "a"); + if (!f) { + cout << m << "\n"; + return; + } + fprintf (f, "%s\n", m.c_str ()); fclose (f); } diff --git a/src/lib/util.cc b/src/lib/util.cc index 190bb42b1..d0274e821 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -95,6 +95,7 @@ using std::pair; using std::cout; using std::bad_alloc; using std::streampos; +using std::set_terminate; using boost::shared_ptr; using boost::thread; using boost::lexical_cast; @@ -273,6 +274,31 @@ LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *) } #endif +/* From http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c */ +void +terminate () +{ + static bool tried_throw = false; + + try { + // try once to re-throw currently active exception + if (!tried_throw++) { + throw; + } + } + catch (const std::exception &e) { + std::cerr << __FUNCTION__ << " caught unhandled exception. what(): " + << e.what() << std::endl; + } + catch (...) { + std::cerr << __FUNCTION__ << " caught unknown/unhandled exception." + << std::endl; + } + + stacktrace (cout, 50); + abort(); +} + /** Call the required functions to set up DCP-o-matic's static arrays, etc. * Must be called from the UI thread, if there is one. */ @@ -309,7 +335,9 @@ dcpomatic_setup () boost::filesystem::path lib = app_contents (); lib /= "lib"; setenv ("LTDL_LIBRARY_PATH", lib.c_str (), 1); -#endif +#endif + + set_terminate (terminate); libdcp::init (); -- 2.30.2