changeset 20633:ffc6cdcd02c5 stable

Fix segfault when complex double matrix calls ZGETRF (bug #45577). * CMatrix.cc (finverse, determinant, rcond, fsolve): Calculate norm of matrix and if it is NaN, skip calling ZGETRF in LAPACK and set info to non-zero value to signal an error.
author Rik <rik@octave.org>
date Sat, 10 Oct 2015 16:46:00 -0700
parents 7890893a0e69
children 1c5a86b7f838
files liboctave/array/CMatrix.cc
diffstat 1 files changed, 26 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/array/CMatrix.cc	Thu Oct 08 20:59:25 2015 -0400
+++ b/liboctave/array/CMatrix.cc	Sat Oct 10 16:46:00 2015 -0700
@@ -1131,11 +1131,14 @@
 
       // Calculate the norm of the matrix, for later use.
       double anorm;
-      if (calc_cond)
-        anorm = retval.abs ().sum ().row (static_cast<octave_idx_type>(0))
-                .max ();
-
-      F77_XFCN (zgetrf, ZGETRF, (nc, nc, tmp_data, nr, pipvt, info));
+      //if (calc_cond)   // Must always calculate anorm for bug #45577 
+      anorm = retval.abs ().sum ().row (static_cast<octave_idx_type>(0)).max ();
+
+      // Work around bug #45577, LAPACK crashes Octave if norm is NaN
+      if (xisnan (anorm))
+        info = -1;
+      else
+        F77_XFCN (zgetrf, ZGETRF, (nc, nc, tmp_data, nr, pipvt, info));
 
       // Throw-away extra info LAPACK gives so as to not change output.
       rcon = 0.0;
@@ -1698,9 +1701,14 @@
 
           // Calculate the norm of the matrix, for later use.
           double anorm = 0;
-          if (calc_cond) anorm = xnorm (*this, 1);
-
-          F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+          //if (calc_cond)   // Must always calculate anorm for bug #45577 
+          anorm = xnorm (*this, 1);
+
+          // Work around bug #45577, LAPACK crashes Octave if norm is NaN
+          if (xisnan (anorm))
+            info = -1;
+          else
+            F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
 
           // Throw-away extra info LAPACK gives so as to not change output.
           rcon = 0.0;
@@ -1891,7 +1899,11 @@
               Array<double> rz (dim_vector (2 * nc, 1));
               double *prz = rz.fortran_vec ();
 
-              F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+              // Work around bug #45577, LAPACK crashes Octave if norm is NaN
+              if (xisnan (anorm))
+                info = -1;
+              else
+                F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
 
               if (info != 0)
                 {
@@ -2225,7 +2237,11 @@
             anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0))
                     .max ();
 
-          F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
+          // Work around bug #45577, LAPACK crashes Octave if norm is NaN
+          if (xisnan (anorm))
+            info = -2;
+          else
+            F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info));
 
           // Throw-away extra info LAPACK gives so as to not change output.
           rcon = 0.0;