octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #47381] unwind_protect_cleanup block not run f


From: Rik
Subject: [Octave-bug-tracker] [bug #47381] unwind_protect_cleanup block not run for some errors in C++ code
Date: Thu, 10 Mar 2016 19:41:54 +0000
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0

Follow-up Comment #3, bug #47381 (project octave):

The problem is in gl2ps_print.cc.  


      // Copy temporary file to pipe
      gnulib::fseek (tmpf, 0, SEEK_SET);
      char str[256];
      int nread = 1;
      while (! feof (tmpf) && nread)
        {
          nread = gnulib::fread (str, 1, 256, tmpf);
          if (nread)
            gnulib::fwrite (str, 1, nread, fp);
        }


If the pipe is closed, because the command failed, then this code does not
detect that condition nor raise an error.  Instead, the call to gnulib::fwrite
sends a signal SIGPIPE which is caught by Octave's signal handler over in
sighandlers.cc.


#ifdef SIGPIPE
static void
sigpipe_handler (int /* sig */)
{
  octave_signal_caught = 1;

  octave_signals_caught[SIGPIPE] = true;

  // Don't loop forever on account of this.

  if (pipe_handler_error_count++ > 100 && octave_interrupt_state >= 0)
    octave_interrupt_state++;
}
#endif


Since the file being copied is quite large (potentially MB of eps data) the
pipe_handler_error_count eventually exceeds 100 and Octave's interrupt state
gets set.  Thus, when the drawnow function call eventually returns the
interpreter detects that and returns to the command line immediately bypassing
the unwind_protect_cleanup blocks.

I tried this


# HG changeset patch
# User Rik <address@hidden>
# Date 1457638063 28800
#      Thu Mar 10 11:27:43 2016 -0800
# Node ID 91d825a9f5c993597fb2b85cce490d0b67c29b84
# Parent  067662ac6bfea2cd70b6f176080e330d5317d499
Raise an error if writes to pipe fail (bug #47381).

* gl2ps-print.cc (gl2ps_renderer::draw): When copying temporary file to pipe,
check that write succeeds.  Raise an error if it does not, rather than
letting SIGPIPE interrupt handler eventually deal with the problem.

diff -r 067662ac6bfe -r 91d825a9f5c9 libinterp/corefcn/gl2ps-print.cc
--- a/libinterp/corefcn/gl2ps-print.cc  Wed Mar 09 20:05:27 2016 -0500
+++ b/libinterp/corefcn/gl2ps-print.cc  Thu Mar 10 11:27:43 2016 -0800
@@ -269,12 +269,17 @@ gl2ps_renderer::draw (const graphics_obj
       // Copy temporary file to pipe
       gnulib::fseek (tmpf, 0, SEEK_SET);
       char str[256];
-      int nread = 1;
+      size_t nread, nwrite;
+      nread = 1;
       while (! feof (tmpf) && nread)
         {
           nread = gnulib::fread (str, 1, 256, tmpf);
           if (nread)
-            gnulib::fwrite (str, 1, nread, fp);
+            {
+              nwrite = gnulib::fwrite (str, 1, nread, fp);
+              if (nwrite != nread)
+                error ("gl2ps_renderer::draw: internal pipe error");
+            }
         }
     }
   else


and it seems to work.  The possible changeset is attached to the report as
SIGPIPE.cset, and needs review.

One thing I notice is that this sequence works.


sombrero
print -dfoo tst1.png
print -dpng tst2.png
warning: broken pipe


But, it produces the extra message "warning: broken pipe".  This comes from
octave_signal_handler in sighandlers.cc.  It is a minor quibble, but maybe it
indicates that the patch should take a different direction.  Instead of
calling error when a bad pipe condition is detected it could call
octave_signal_handler.  That would reset the state of SIGPIPE, as well as
print the warning message correctly attached to the command that caused it.

Or maybe we should be setting up Octave to ignore SIGPIPE signals when running
this code.  That sounds like more work, and I don't know exactly how to do
it.


(file #36599)
    _______________________________________________________

Additional Item Attachment:

File name: SIGPIPE.cset                   Size:1 KB


    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?47381>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]