Various OOM fixes; fancy terminate() handler.
authorCarl Hetherington <cth@carlh.net>
Sun, 9 Feb 2014 23:34:24 +0000 (23:34 +0000)
committerCarl Hetherington <cth@carlh.net>
Sun, 9 Feb 2014 23:34:24 +0000 (23:34 +0000)
ChangeLog
src/lib/job.cc
src/lib/log.cc
src/lib/util.cc

index 0d3633cbd15dda2045ec4d93806ecd97b1a0a430..0a6f529593488f6a08cef3a01b92568f607093d5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2014-02-09  Carl Hetherington  <cth@carlh.net>
 
+       * 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.
index 9981934ec93767d1286ff459acbe3845de9af821..66fa3755dfb69d3c751a15cde8c868d083927339 100644 (file)
@@ -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);
        }
 }
 
index 9ddf460d43ccc1c382270e607a7634a66be09049..e79f0e201ca69cfab04a0a9db453cd1c95810dc0 100644 (file)
@@ -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);
 }
index 190bb42b19ab01ec7fe5dc4ca291a1e4d16b6c37..d0274e8215ce78e95a69cbe9cbc80655aa0980d9 100644 (file)
@@ -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 ();