bugGNU Octave - Bugs: bug #44292, Frequent crashes when printing to...

 
 

bug #44292: Frequent crashes when printing to eps on Windows XP platform

Submitted by:  Rik <rik5>
Submitted on:  Wed 18 Feb 2015 05:02:46 PM UTC  
 
Category:  Plotting with OpenGL Severity:  5 - Blocker
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  Closed
Release:  dev Operating System:  Microsoft Windows

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

( Jump to the original submission)

Thu 03 Dec 2015 04:23:39 AM UTC, comment #25: 

I can no longer reproduce this using the default branch with tip 20787:62564952e161.  I think there have been enough changes, including Pantxo's addition of a small delay in order for the graphics subsystem to get a lock, that this may have been resolved.  In any case, even without knowing the exact resolving changeset I'm closing this report.

Rik <rik5>
Project Administrator
Tue 31 Mar 2015 12:19:03 AM UTC, comment #24: 

Things have gotten slightly better, but I can still cause a segfault from time to time.  I used to be able to get this with just sombrero, but now I have to use surfc which is an even more complicated drawing.

demo ("surfc", 1)
print -depsc tst.eps
print -deps tst.eps
print -depsc tst.eps

Rik <rik5>
Project Administrator
Mon 02 Mar 2015 06:19:57 PM UTC, comment #23: 

So that leaves the Win XP normal printing issues you've seen, but I can't replicate that at the moment on Linux.

One thing I've just noticed about OSMesa, having still some debugging cruft in my code, is that the normal print routine (i.e., the non visible-off) has very much the same path as OSMesa and those OpenGL calls are working fine for (is it) Qt.  I'll have to look into how OpenGL is installed under the Qt environment.  Maybe there is a simple oversight there about switching the context to OSMesa.

Dan Sebald <sebald>
Mon 02 Mar 2015 05:00:19 PM UTC, comment #22: 

@Dan: I committed your patch to more closely verify the input to drawnow (http://hg.savannah.gnu.org/hgweb/octave/rev/e814e202cd84).

I wouldn't worry too much about OSMESA printing since we only use it for off-screen printing which really means the documentation figures.  Those figures will be generated and shipped in a tarball so it isn't absolutely critical that Window's users be able to off-screen print.

It does seem to be an issue that general eps printing can cause a segfault since that can be expected to happen frequently.

Rik <rik5>
Project Administrator
Mon 02 Mar 2015 09:14:21 AM UTC, comment #21: 

I'm having very little success with this OpenGL/Mesa code.  If I understand correctly, OSMesa is the hunk of software that creates a context for which the OpenGL routines can be used.  Without reading too much, I gather that the context is a memory buffer and various attributes.  After the context is created, the OpenGL routines such as:

glGetIntegerv(GL_VIEWPORT, viewport);
glGetIntegerv (GL_DEPTH_BITS, &z);
etc.

may be run to access/utilize the OpenGl engine.  OK, and then this extension of sorts, GL2PS, allows one to use the OpenGL graphics engine to create PostScript output files.  That is, these

gl2psBeginPage();
etc.

functions can be thought of as just another glXYZ function.

However, although the context creation works fine:

  OSMesaContext ctx = OSMesaCreateContextExt (OSMESA_RGBA, 16, 0, 0, NULL);
  // Bind the buffer to the context and make it current
  if (! OSMesaMakeCurrent (ctx, buffer, GL_UNSIGNED_BYTE, Width, Height))

Every OpenGL routine after that immediately seg-faults.  I can change the functions around, comment some out.  I'm wondering if I'm missing something:

https://www.opengl.org/wiki/Getting_Started#Getting_Functions

"
If you are using C/C++, read on.

In order to use OpenGL, you must get OpenGL API functions. For most libraries you are familiar with, you simply #include a header file, make sure a library is linked into your project or makefile, and it all works. OpenGL doesn't work that way.

For reasons that are ultimately irrelevant to this discussion, you must manually load functions via a platform-specific API call. This boilerplate work is done with various OpenGL loading libraries; these make this process smooth. You are strongly advised to use one.

If you want to do it manually however, there is a guide as to how to load functions manually. You still should use an extension loader.
"

So how are the functions being "loaded"?  Is it by some library that is being included with the project?  Is there some function call that needs to be done to make all the OpenGL functions operate correctly?

Dan Sebald <sebald>
Sun 01 Mar 2015 09:04:40 PM UTC, comment #20: 

OK, if that DLL is ruled out, the empty feedback buffer and the bogus image sizes of the other report would suggest some kind of bad pointer or something.  That's at least a clue.

A couple days ago I had investigated up to the rend.draw() function because I couldn't find where "rend" is declared.  (Too many occurrences of "rend".)  I sort of verified in my mind that the Mesa libraries were correctly used in the initialization step.  I'm already getting a crash with

  // Test for a bug in OSMesa with version < 9.0
  //
  // Unfortunately the macros OSMESA_MAJOR_VERSION and
  // OSMESA_MINOR_VERSION weren't updated between many releases and
  // can't be used for detection.  (Version 8.0 until 9.1.4 all return
  // MAJOR 6, MINOR 5)
  int z, s;
  glGetIntegerv (GL_DEPTH_BITS, &z);

but I have 7.4 (although that shouldn't cause a crash, plus I can skip this step) and can't compile 9+ series right now.  I suppose I could try at least compile the 8.0 series of Mesa and see if that gets any further.

Dan Sebald <sebald>
Sun 01 Mar 2015 08:22:51 PM UTC, comment #19: 

On bug #44338 I investigated the dxtn.dll issue.  That is just a warning about an obscure compression standard which we aren't using anyways.  I believe it is a red herring.

Rik <rik5>
Project Administrator
Sun 01 Mar 2015 07:50:46 PM UTC, comment #18: 

It looks like you are now running into the "rend.draw()" problem that I was having--or actually it might be a different issue associated with that, because "Mesa warning: couldn't open dxtn.dll" isn't a warning that I'd get in Linux.  In this case, I think you are missing that dxtn.dll on your system, but why Mesa wants to do compression I have no idea.  If Mesa is in fact properly looking for the dll, then the Octave code isn't properly handling the missing DLL scenario.

On the other hand, it could stem from the same issue and just be a different manifestation because in https://savannah.gnu.org/bugs/?44338 it seems the characteristics of the failure get progressively worse with successive calls, and in an odd way with negative window sizes.

I don't have Windows, but I can search for the issue with rend.draw().

Dan Sebald <sebald>
Sun 01 Mar 2015 07:28:09 PM UTC, comment #17: 

Unfortunately, I still seem to get segfaults even with your latest patch.  I have to review the patch more, it looks like it is worth committing even if it doesn't solve this particular bug report.  But with it applied, I ran under Windows

>> surf (peaks)
>> set (1, 'visible', 'off')
>> print -depsc tst.eps
Mesa warning: couldn't open dxtn.dll, software DXTn compression/decompression unavailable
warning: gl2ps-renderer::draw: empty feedback buffer and/or nothing else to print
warning: called from
    __opengl_print__ at line 171 column 7
    print at line 431 column 14

Separately, If I just print repeatedly to -depsc or -deps I can get Windows XP to segfault.

Rik <rik5>
Project Administrator
Sat 28 Feb 2015 09:49:13 AM UTC, comment #16: 

The changes with the new code

                  if (! file.empty () && file[0] == '|')
                    file = file.substr (1);  // Strip leading pipe character

are more robust than previous.  However, I can still get the following behavior:

octave:1> surf (peaks)
octave:2> print -depsc tst.eps
pipeline =
{
  [1,1] = /dev/null
}
error: drawnow: nonexistent directory ' | /dev/'
error: called from
    __opengl_print__ at line 172 column 7
    print at line 431 column 14
octave:2>

and

octave:1> surf (peaks)
octave:2> print -depsc tst.eps
sh: -c: line 0: syntax error near unexpected token `|'
sh: -c: line 0: ` |'
warning: broken pipe
pipeline =
{
  [1,1] =
}
octave:2>

by massaging the pipeline whitespace.  I know it is a contrived situation, but still drawnow() is a user-callable function.

Also, I suspect that the current, recently added changes to _osmesa_print_.cc could result in a segmentation fault if the string is tweaked in the wrong way.  However, I'm having problems with seg faults elsewhere after building with the new OSMesa code--related to the osmesa library being out of date probably (v. 7.9, but I can't compile the latest 10.2 OSMesa because it wants recent GLProto, which is getting into x11 files, something I don't want to deal with now) and rend.draw() which is also crashing, but I'm not sure why.

I've attached a patch that I think handles all situations of white space and bogus file names in an organized way.  Please try it and let me know how OSMesa print is working for you.  E.g.,

octave:1> surf (peaks)
octave:2> set (1, 'visible', 'off');
octave:3> print -depsc tst.eps
panic: Segmentation fault -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
Segmentation fault (core dumped)

That seg fault is occurring before even reaching the changeset hunk.

(file #33209)

Dan Sebald <sebald>
Fri 27 Feb 2015 06:03:31 PM UTC, comment #15: 

@Dan: Very good catch.  I applied your patch here (http://hg.savannah.gnu.org/hgweb/octave/rev/60fe3ef12bb0).  I also found several other dodgy instances in the Octave code base which I corrected (http://hg.savannah.gnu.org/hgweb/octave/rev/ed5ee3f610db).

I now have to rebuild MXE octave and test in a Windows VM so it will be several hours, but I have a hunch this is a big part of the problem.

Rik <rik5>
Project Administrator
Fri 27 Feb 2015 01:03:23 AM UTC, comment #14: 

Oh, it may or may not be a pipe.  (On linux it is.)  I see that the expression entered for the pipeline is decomposed in the function

DEFUN (drawnow, args, ,

in graphics.cc.  The file name is then used to open a file of sort.  I suppose this is to handle OS's not having a pipe.

I have done some debugging.  After adding some fprintf() statements to graphics.c and saving, I find it takes 2 minutes and 38 seconds to recompile and link Octave.  Despite that, I persevered and slogged through trial-and-error compilation.

If I pass the empty string in for the pipeline argument, i.e.,

+    drawnow (gl2ps_device{n}, "");

and run with the --no-gui option that the standard error output can be seen.  The first time I attempted to "print -depsc tst.eps", I saw no crash.  However, subsequent "print -depsc tst.eps" tests resulted in the following error:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr
panic: Aborted -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
Aborted (core dumped)

In the file graphics.cc, function drawnow() is this test

                  size_t pos = file.find_first_not_of ("|");
                  if (pos > 0)
                    file = file.substr (pos);

but size_t variables are not signed so that test >0 always passes.  Apparently passing in what is effectively the maxim string length to the substr() routine causes problems.  I've attached a changeset that properly tests for "not found".  With that change, I'm seeing the following result for the empty string pipeline:

octave:1> surf (peaks)
octave:2> print -depsc tst.eps
warning: broken pipe

octave:2>

which looks correct.  Please apply the changeset and check if that helps in the Windows case.  Probably not, but who knows.

I was going to include a second changeset for what I think should be a check for a file being opened correctly in the gl2ps_print() function.  That isn't causing a problem that I'm aware of.  However, I see that change was made recently in the canonical repository.

(file #33198)

Dan Sebald <sebald>
Thu 26 Feb 2015 08:54:39 PM UTC, comment #13: 

diff --git a/scripts/plot/util/private/__opengl_print__.m b/scripts/plot/util/pr
--- a/scripts/plot/util/private/__opengl_print__.m
+++ b/scripts/plot/util/private/__opengl_print__.m
@@ -162,7 +162,7 @@ function opts = __opengl_print__ (opts)
     if (opts.debug)
       fprintf ("opengl-pipeline: '%s'\n", pipeline{n});
     endif
-    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));
+    drawnow (gl2ps_device{n}, "");
   endfor

   if (! isempty (strfind (opts.devopt, "standalone")))

Dan Sebald <sebald>
Thu 26 Feb 2015 08:53:18 PM UTC, comment #12: 

Did you try substituting a null device for the pipe and see if that alleviates the problem?  Something like

diff --git a/scripts/plot/util/private/__opengl_print__.m b/scripts/plot/util/pr
--- a/scripts/plot/util/private/__opengl_print__.m
+++ b/scripts/plot/util/private/__opengl_print__.m
@@ -162,6 +162,8 @@ function opts = __opengl_print__ (opts)
     if (opts.debug)
       fprintf ("opengl-pipeline: '%s'\n", pipeline{n});
     endif
+pipeline
+pipeline{n} = "/dev/null"
     drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));
   endfor

It doesn't take much to make Octave crash on a Linux system with regard to that pipe.  The following will do it:

diff --git a/scripts/plot/util/private/__opengl_print__.m b/scripts/plot/util/pr
--- a/scripts/plot/util/private/__opengl_print__.m
+++ b/scripts/plot/util/private/__opengl_print__.m
@@ -162,7 +162,7 @@ function opts = _opengl_print_ (opts)
     if (opts.debug)
       fprintf ("opengl-pipeline: '%s'\n", pipeline{n});
     endif
-    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));
+    drawnow (gl2ps_device{n}, "");
   endfor

   if (! isempty (strfind (opts.devopt, "standalone")))
-verbatim-

The program shouldn't crash just because the input of some function doesn't make sense.  I'd say investigate that problem and you might discovery what the problem is specific to Windows.

Dan Sebald <sebald>
Wed 25 Feb 2015 01:33:49 AM UTC, comment #11: 

I tried stepping through using the GUI and breakpoints and it wouldnt crash at that point.

Running normally, it would crash about 99% of the time on that machine.

John Donoghue <lostbard>
Project Member
Wed 25 Feb 2015 01:29:31 AM UTC, comment #10: 

This definitely seems to be related to a memory issue.  When I run Octave on Windows under gdb.exe I can't get it to crash.  However, as soon as I run regularly I can get it to crash with sombrero easily.  I was trying to get a backtrace, but was unable to generate a failure under gdb.

Rik <rik5>
Project Administrator
Fri 20 Feb 2015 08:28:49 PM UTC, comment #9: 

Just for the record, the Matlab support is stated here;
http://www.mathworks.com/support/sysreq/roadmap.html

Michael Godfrey <godfrey>
Project Member
Fri 20 Feb 2015 08:11:03 PM UTC, comment #8: 

Windows XP is an unsupported platform by Microsoft.  I only use it because it's all that I have around for testing.  If it works okay in newer wersions of Windows then maybe we just close this report.  What versions of Windows should we claim to support on the Octave web page?

Rik <rik5>
Project Administrator
Thu 19 Feb 2015 06:55:19 PM UTC, comment #7: 

It also crashes when running _run_tests_ at plot\draw\contour.m

Prior testes of draw\area.m, and draw\compass.m were ok.

John Donoghue <lostbard>
Project Member
Thu 19 Feb 2015 06:45:35 PM UTC, comment #6: 

Running on a old Xp machine I see similar issues.

If I run a very simple plot plot([1]) it doesn't crash.

Printing sombrero crashes in any format

John Donoghue <lostbard>
Project Member
Wed 18 Feb 2015 07:44:39 PM UTC, comment #5: 

(Just sort of writing notes here.)  If the error seems to be happening with gl2ps library, then the function that is called is in graphics.cc:

                              go.get_toolkit ().print_figure (go, term, file,
                                                              mono, debug_file);

Dan Sebald <sebald>
Wed 18 Feb 2015 07:42:08 PM UTC, comment #4: 

Print ends up using drawnow().  In my _opengl_print_.m file in the scripts/plot/private directory I printed out

gl2ps_device{n}
pipeline{n}
strcat ('|',pipeline{n})
    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));

and see

ans = epsis2D
ans =  cat > 'junk.eps'
ans = | cat > 'junk.eps'

So, the graphics engine is being piped to the cat function which is redirected to the file.  The question is if the error happens before the pipe output (e.g., the gl2ps library), or maybe on the MXE system it is the pipe onward that doesn't work so well.  It is WIN emulation after all, could have a bug.  Is there some other system command that could be used?

It doesn't take much for me to make linux Octave crash by tweaking these settings.  For example, removing the right side of the pipe does it:

gl2ps_device{n}
pipeline{n} = ""
strcat ('|',pipeline{n})
    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));

On the other hand, I can keep the pipe from crashing with

gl2ps_device{n}
pipeline{n} = "/dev/null"
strcat ('|',pipeline{n})
    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));

If the latter consistently prevents a crash for you, it might indicate the problem is not the gl2ps library, but something flaky with the pipe setup.

Dan Sebald <sebald>
Wed 18 Feb 2015 06:43:50 PM UTC, comment #3: 

The only information to stderr is that there has been a segmentation violation (no details) and that Octave is trying to save the workspace.

gnuplot works fine.  Either FLTK or Qt will segfault eventually.  This suggests either our OpenGL render code, or more likely, the gl2ps library.

Rik <rik5>
Project Administrator
Wed 18 Feb 2015 06:22:18 PM UTC, comment #2: 

Oh, and the toolkit as well.  I suppose that makes a difference with "print".

Dan Sebald <sebald>
Wed 18 Feb 2015 06:21:08 PM UTC, comment #1: 

Could you run octave in the GUI and CLI environments to see if there is some type of useful error message that shows up somewhere associated with stderr?

Dan Sebald <sebald>
Wed 18 Feb 2015 05:02:46 PM UTC, original submission:  

It's possibly not 100%, but probably 3/4 of the time I can provoke a crash with the following code in the GUI on a Windows XP virtual machine.

surf (peaks)
print -depsc tst.eps
print -deps tst.eps
print -depsc tst.eps

I tried using different file names to see if it was an issue with the delete command but I still get a segfault.  This doesn't happen on Linux.

Rik <rik5>
Project Administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #33209:  octave-pipeline_decode-djs2015feb28.patch added by sebald (4KiB - application/octet-stream)
file #33198:  octave-substring_error-djs2015feb26.patch added by sebald (898B - application/octet-stream)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by godfrey (Posted a comment)
  • -email is unavailable- added by lostbard (Posted a comment)
  • -email is unavailable- added by sebald (Posted a comment)
  • -email is unavailable- added by rik5 (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

     

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-12-03 rik5 StatusNone => Fixed
        Open/ClosedOpen => Closed
    2015-03-04 rik5 SummaryFrequent crashes when printing to eps on Windows platform => Frequent crashes when printing to eps on Windows XP platform
    2015-02-28 sebald Attached File- => Added octave-pipeline_decode-djs2015feb28.patch, #33209
    2015-02-27 sebald Attached File- => Added octave-substring_error-djs2015feb26.patch, #33198
    2015-02-18 rik5 Severity3 - Normal => 5 - Blocker
    2015-02-18 rik5 CategoryInterpreter => Plotting with OpenGL

    Back to the top


    Powered by Savane 3.5