changeset 24260:0f2dc8d6c34d stable

Eliminate possible segfaults related to not cleaning up Qhull workspace. * __delaunayn__.cc (free_qhull_memor): Change function name in error message to "__delaunayn__". * __voronoi__.cc, convhulln.cc (free_qhull_memory): New function with code to clear temporary Qhull memory. * __voronoi__.cc, convhulln.cc (F__voronoi__, Fconvhulln): Use frame.add_fcn to guarantee that free_qhull_memory() is called whenever function exits.
author Rik <rik@octave.org>
date Thu, 16 Nov 2017 11:54:20 -0800
parents bffbc95fa72b
children 554c630c9835 ec4ec2f7029d
files libinterp/dldfcn/__delaunayn__.cc libinterp/dldfcn/__voronoi__.cc libinterp/dldfcn/convhulln.cc
diffstat 3 files changed, 33 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__delaunayn__.cc	Wed Nov 15 19:26:38 2017 -0800
+++ b/libinterp/dldfcn/__delaunayn__.cc	Thu Nov 16 11:54:20 2017 -0800
@@ -77,7 +77,7 @@
   qh_memfreeshort (&curlong, &totlong);
 
   if (curlong || totlong)
-    warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
+    warning ("__delaunayn__: did not free %d bytes of long memory (%d pieces)",
              totlong, curlong);
 }
 
--- a/libinterp/dldfcn/__voronoi__.cc	Wed Nov 15 19:26:38 2017 -0800
+++ b/libinterp/dldfcn/__voronoi__.cc	Thu Nov 16 11:54:20 2017 -0800
@@ -62,6 +62,19 @@
   std::fclose (f);
 }
 
+static void
+free_qhull_memory ()
+{
+  qh_freeqhull (! qh_ALL);
+
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong)
+    warning ("__voronoi__: did not free %d bytes of long memory (%d pieces)",
+             totlong, curlong);
+}
+
 static bool
 octave_qhull_dims_ok (octave_idx_type dim, octave_idx_type n, const char *who)
 {
@@ -162,6 +175,9 @@
 
   int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
                                ismalloc, cmd_str, outfile, errfile);
+
+  frame.add_fcn (free_qhull_memory);
+
   if (exitcode)
     error ("%s: qhull failed", caller.c_str ());
 
@@ -319,16 +335,6 @@
 
   retval = ovl (F, C, at_inf);
 
-  // Free memory from Qhull
-  qh_freeqhull (! qh_ALL);
-
-  int curlong, totlong;
-  qh_memfreeshort (&curlong, &totlong);
-
-  if (curlong || totlong)
-    warning ("%s: qhull did not free %d bytes of long memory (%d pieces)",
-             caller.c_str (), totlong, curlong);
-
   return retval;
 
 #else
--- a/libinterp/dldfcn/convhulln.cc	Wed Nov 15 19:26:38 2017 -0800
+++ b/libinterp/dldfcn/convhulln.cc	Thu Nov 16 11:54:20 2017 -0800
@@ -57,6 +57,19 @@
   std::fclose (f);
 }
 
+static void
+free_qhull_memory ()
+{
+  qh_freeqhull (! qh_ALL);
+
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong)
+    warning ("convhulln: did not free %d bytes of long memory (%d pieces)",
+             totlong, curlong);
+}
+
 static bool
 octave_qhull_dims_ok (octave_idx_type dim, octave_idx_type n, const char *who)
 {
@@ -179,6 +192,9 @@
 
   int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
                                ismalloc, cmd_str, outfile, errfile);
+
+  frame.add_fcn (free_qhull_memory);
+
   if (exitcode)
     error ("convhulln: qhull failed");
 
@@ -280,16 +296,6 @@
 
   retval(0) = idx;
 
-  // Free memory from Qhull
-  qh_freeqhull (! qh_ALL);
-
-  int curlong, totlong;
-  qh_memfreeshort (&curlong, &totlong);
-
-  if (curlong || totlong)
-    warning ("convhulln: did not free %d bytes of long memory (%d pieces)",
-             totlong, curlong);
-
   return retval;
 
 #else