bugGNU Octave - Bugs: bug #58814, Abort, core dump on exiting from...

 
 

bug #58814: Abort, core dump on exiting from graphics code

Submitted by:  None
Submitted on:  Thu 23 Jul 2020 10:23:14 PM UTC  
 
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Ready For Test Assigned to:  None
Originator Name:  Originator Email:  -email is unavailable-
Open/Closed:  Open Release:  dev
Operating System:  GNU/Linux

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)

Fri 14 Aug 2020 05:08:28 AM UTC, comment #23: 

I pushed the following changeset to stable and merged with default:

http://hg.savannah.gnu.org/hgweb/octave/rev/c315a866dbe9

Marking ready for test, but close if you agree this is fixed, at least well enough for now, and for the release.  I assume this will also fix the random crashing problems we've been seeing with generating figures for the manual, but I guess only time will tell.

John W. Eaton <jwe>
Project Administrator
Fri 14 Aug 2020 12:18:09 AM UTC, comment #22: 

@jwe: The last patch with "close all" works for me.  I tested many times with the original code, tst_segfault.m (attached), and with the non-overlapping code in tst_segfault2.m.  Previously, I would generate a SIGABRT every time, or at least every other time, so this is definitely more solid.

(file #49670)

Rik <rik5>
Project Administrator
Fri 14 Aug 2020 12:15:30 AM UTC, comment #21: 

@jwe in comment #20: That was an absolutely perfect fix! Here are the test results from applying interp-shutdown-reorder-diffs-2.txt:

$ /usr/bin/time --verbose octave mytest.m
        Command being timed: "octave mytest.m"
        {{{ SNIP }}}
        Exit status: 0

$ /usr/bin/time --verbose octave tst_segfault2.m
        Command being timed: "octave tst_segfault2.m"
        {{{ SNIP }}}
        Exit status: 0

$ /usr/bin/time --verbose octave tst_spy.m
        Command being timed: "octave tst_spy.m"
        {{{ SNIP }}}
        Exit status: 0

Not a single warning or error. Thank you so much!

Anonymous
Thu 13 Aug 2020 10:39:15 PM UTC, comment #20: 

Another update:

With Octave built from hg id bdc53d9affb2 and using the tst_segfault2.m script, I can usually generate a crash at exit if I select the "rotate" toolbar icon in one of the figures and rotate the figure as Octave is exiting.  That also happens for me with my patches.

Following an idea from comment #13, I added "close all" to the end of the tst_segfault2.m script and it seemed to help.  So I removed that and added

  OCTAVE_SAFE_CALL (feval, ("close", ovl ("all"), 0));

as the first thing in the interpreter:shutdown function.  That also seemed to work without needing any calls to sleep.

A new patch is attached (interp-shutdown-reorder-diffs-2.txt).  Does this change work for anyone else?

(file #49669)

John W. Eaton <jwe>
Project Administrator
Thu 13 Aug 2020 10:09:52 PM UTC, comment #19: 

it was just an idea. thanks for feedback anyway ;-)

@Rik: with respect to jwe's comment #12: what is your environment?

Hg200 <hg200>
Thu 13 Aug 2020 10:00:57 PM UTC, comment #18: 

@Rik in comment #16: With that code I get the warnings from tst_spy.m **and** the SIGABRT.

$ /usr/bin/time --verbose octave tst_segfault2.m
warning: base_graphics_object::get_properties: invalid graphics object
warning: base_graphics_object::get_properties: invalid graphics object
       {{{ SNIP }}}
warning: base_graphics_object::get_properties: invalid graphics object
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
fatal: caught signal Aborted -- stopping myself...
Command terminated by signal 6
        Command being timed: "octave tst_segfault2.m"
            {{{ SNIP }}}
        Exit status: 0

Anonymous
Thu 13 Aug 2020 09:49:59 PM UTC, comment #17: 

@Hg200 in comment 15: I added a short pause statement inside the loop that draws the 10 figures and quickly minimized each figure window as it showed up. No SIGABRT.

$ /usr/bin/time --verbose octave mytest.m
   Command being timed: "octave mytest.m"
       {{{ SNIP }}}
   Exit status: 0

However: tst_spy.m in comment #8 has 28 overlapping figures (all spy plots) that only cause warnings on exit not aborts.

Anonymous
Thu 13 Aug 2020 09:49:56 PM UTC, comment #16: 

I used the "position" property of each figure to guarantee no overlap.  I still get a std::bad_cast and an abort.  The script tst_segfault2.m is attached if you want to try on your own computer.

(file #49665)

Rik <rik5>
Project Administrator
Thu 13 Aug 2020 09:16:09 PM UTC, comment #15: 

regarding Rik's segfault, i am not so deep into the code, so can be absolutely wrong but it is a vague feeling i am asking myself regarding comment #2:

opengl_renderer::draw_patch is called by canvas, hence lives in the gui thread and should be basically a qt paint event, right? i think it will also run if a notify event is triggered. that is when a window of a figure is closed which is obscuring another figure window. but that can happen during shut down.

i am asking myself if the segfault also occurs if the windows don't overlap in the tst_segfault.m example?

Hg200 <hg200>
Thu 13 Aug 2020 08:55:03 PM UTC, comment #14: 

The first patch also executes gh_manager::close_all_figures inside the interpreter::shutdown function.  The intent is to do the same as executing "close all" in the script.  So somehow it is not working properly in the interpreter::shutdown context?

John W. Eaton <jwe>
Project Administrator
Thu 13 Aug 2020 08:33:46 PM UTC, comment #13: 

All this is with Qt 5.15, Linux kernel 5.4.52, libc 2.31, using GCC 10.1.0 and also when repeated with Clang 10.0.0.

Using "/usr/bin/time --verbose" is a hack to get info about programs that crash on exit. This was the result for all three cases: the unpatched version, applying patch 1 alone, and applying patch 1 + patch 2 both.

$ /usr/bin/time --verbose octave mytest.m
warning: base_graphics_object::get_properties: invalid graphics object
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
fatal: caught signal Aborted -- stopping myself...
Command terminated by signal 6
        Command being timed: "octave mytest.m"
        {{{ SNIP }}}
        Exit status: 0

It was terminated by signal 6 (SIGABRT) in all three cases, not a SIGSEGV.

Appending a "close all" (*note*: close all, not clear all) statement to the very end of mytest.m doesn't let Octave exit until the figures are all closed, and there's no SIGABRT:

$ time --verbose octave mytest.m
        Command being timed: "octave mytest.m"
  {{{ SNIP }}}
        Exit status: 0

The foocls test, both with and without the sombrero, works perfectly with patch1 alone, and also with patch1 + patch2. With the original unpatched version it gives SIGABRT:

$ /usr/bin/time --verbose octave
{{{ SNIP }}}

octave:1> foocls
ans =

  foocls object with properties:

octave:2> exit
pure virtual method called
terminate called without an active exception
fatal: caught signal Aborted -- stopping myself...
Command terminated by signal 6
        Command being timed: "octave"
    {{{ SNIP }}}
        Exit status: 0

Anonymous
Thu 13 Aug 2020 07:35:08 PM UTC, comment #12: 

RE: Comment #10, yes, I think we need to execute the equivalent of "clear all" to run destructors for class objects and clear all functions (so persistent variables, which might also be class objects, are also deleted) before we get to the point of calling the destructor on the symbol table.  So I think the patch to reorder things in the interpreter::shutdown function should be applied anyway.

RE Comment #11, what is your build environment?  I assume Linux, but which one, and which version of GCC?

John W. Eaton <jwe>
Project Administrator
Thu 13 Aug 2020 07:06:47 PM UTC, comment #11: 

Unfortunately I still get segfaults on shutdown with the patch applied and with the second diff applied on top of the patch.

Rik <rik5>
Project Administrator
Thu 13 Aug 2020 06:54:30 PM UTC, comment #10: 

1.) are we currently talking about signal "abort" or signal "segfault" or both?

2.) i've never been able to recreate segfaults (concerning test suite as reported in bug #57591 or concerning comment #1 of this bug report), but if i run the following class and quit Octave with "ctrl-d", i can see an abort signal also without invoking a graphic instance (notice that the "sombrero" keyword is missing):

classdef foocls < handle
  methods
    function delete (obj)
      fprintf (stderr, "foocls: foo-i-hithere\n");
    end
  end
end

the testing procedure is:

octave:1> foocls
ans =

  foocls object with properties:


octave:2> ##press "ctrl-d" to exit here
pure virtual method called
terminate called without an active exception
fatal: caught signal Aborted -- stopping myself...
Aborted (core dumped)

- hg update -C 5b1143d1d74b
- backtrace attached
- and this is the last thing i can see in ddd:

  /**
   *  @brief  A smart pointer with reference-counted copy semantics.
   *
   *  The object pointed to is deleted when the last shared_ptr pointing to
   *  it is destroyed or reset.
  */
  template<typename _Tp>
    class shared_ptr : public __shared_ptr<_Tp>
    {
      template<typename... _Args>
        using _Constructible = typename enable_if<
          is_constructible<__shared_ptr<_Tp>, _Args...>::value
        >::type;

the good news is now that your patch from file #49663 seems to fix this:

octave:1> foocls
ans =

  foocls object with properties:


octave:2>
foocls: foo-i-hithere

(file #49664)

Hg200 <hg200>
Thu 13 Aug 2020 04:53:53 PM UTC, comment #9: 

I'm having some trouble now to reliably cause the crash.

Noticing that the crash was happening when Octave was exiting and still drawing objects, I thought that maybe the problem could be more clearly exposed by adding some delay when drawing some graphics objects.  So I tried the following changes:

diff --git a/libinterp/corefcn/gl-render.cc b/libinterp/corefcn/gl-render.cc
--- a/libinterp/corefcn/gl-render.cc
+++ b/libinterp/corefcn/gl-render.cc
@@ -43,6 +43,7 @@
#include "interpreter-private.h"
#include "oct-opengl.h"
#include "text-renderer.h"
+#include "utils.h"

namespace octave
{
@@ -729,11 +730,20 @@ namespace octave
     else if (go.isa ("axes"))
       draw_axes (dynamic_cast<const axes::properties&> (props));
     else if (go.isa ("line"))
-      draw_line (dynamic_cast<const line::properties&> (props));
+      {
+        draw_line (dynamic_cast<const line::properties&> (props));
+        sleep (0.04);
+      }
     else if (go.isa ("surface"))
-      draw_surface (dynamic_cast<const surface::properties&> (props));
+      {
+        draw_surface (dynamic_cast<const surface::properties&> (props));
+        sleep (0.04);
+      }
     else if (go.isa ("patch"))
-      draw_patch (dynamic_cast<const patch::properties&> (props));
+      {
+        draw_patch (dynamic_cast<const patch::properties&> (props));
+        sleep (0.04);
+      }
     else if (go.isa ("light"))
       draw_light (dynamic_cast<const light::properties&> (props));
     else if (go.isa ("hggroup"))

but it's not clear that had a significant effect, except to make plotting really slow.

While investigating, I noticed that creating an object of the following class would also cause Octave to crash on exit:

classdef foocls < handle
  methods
    function delete (obj)
      fprintf (stderr, "foocls: foo-i-hithere\n");
      sombrero ();
    end
  end
end

To avoid that crash, I reordered some of the actions in the interpreter::shutdown function.  Could someone who is able to reproduce the failure please try the attached patch and report whether it also avoids the problem reported here?

If not, then could you also try the following change, applied in addition to the attached patch?

diff --git a/libinterp/corefcn/interpreter.cc b/libinterp/corefcn/interpreter.cc
--- a/libinterp/corefcn/interpreter.cc
+++ b/libinterp/corefcn/interpreter.cc
@@ -867,6 +867,12 @@ namespace octave

     OCTAVE_SAFE_CALL (m_gh_manager->close_all_figures, ());

+    // Allow graphics operations and callbacks to execute.  Can this job
+    // be done in a way that ensures everything is executed without
+    // waiting for any extra time?
+
+    OCTAVE_SAFE_CALL (sleep, (0.5, true));
+
     // What is supposed to happen if a figure has a closerequestfcn or
     // deletefcn callback registered that creates other figures or
     // variables?  What if those variables are classdef objects with

(file #49663)

John W. Eaton <jwe>
Project Administrator
Sun 09 Aug 2020 12:55:29 PM UTC, comment #8: 

Uploading files tst_spy.m and match9.mat for cases that do not cause segfaults but may cause warnings.

(file #49644, file #49645)

Anonymous
Wed 29 Jul 2020 09:34:42 AM UTC, comment #7: 

I tried to test what Matlab R2020a is doing when cleaning up figures on exit with this script:

hf = figure('DeleteFcn', @createOnDelete);

function createOnDelete(~,~)
  figure('DeleteFcn', @createOnDelete);
end

Using "diary" wasn't really helpful because it seems to close quite early on when exiting.
Instead I'll try and describe what I see on screen:
- When executing the script, an empty figure is displayed.
- When I then close Matlab, that figure closes followed by a new figure that appears on screen.
- After that the main GUI window of Matlab disappears (almost) at the same time as that new figure disappearing.
- A short time after, yet another figure window flashes on screen for the fraction of a second.
- Matlab does not hang around as a ghost process but seems to have closed successfully.

I don't think we need to follow exactly what Matlab is doing here. Just meant as a point of reference.

Markus Mützel <mmuetzel>
Project Member
Sat 25 Jul 2020 09:44:35 AM UTC, comment #6: 

Sorry. I should at least have tried if the code compiles with the change.

I'm still not sure what exactly is going on. But I thought that (somehow) the axes graphics object was destroyed while it was still being initialized.
I'm not sure if a copy-on-write approach would help in that particular case. Wouldn't we have to pass a copy to the GUI thread independent of whether the object might be changed? If the interpreter thread destroys the graphics object before the GUI thread would have had a chance to make its copy, we would see the same issue again, wouldn't we?
In that case, where would the clean-up be done? Would that mean that each thread would need to clean-up their copy of the graphics object when it is deleted?

If that can only happen when Octave closes, it is probably ok to keep the copy of the object and let the OS do its job.
If this could also happen otherwise, I thought it would be ok to just skip the remainder of the initialization. (That is what I was attempting with the failing patch.)

I don't know what is done in which order when Octave closes. But to fix the issue now: Should the GUI thread be unlocked (to finish whatever it has started) before the interpreter destroys the gh_manager?

Markus Mützel <mmuetzel>
Project Member
Fri 24 Jul 2020 10:32:52 PM UTC, comment #5: 

Try looking at the full backtrace for all threads using

thread apply all bt

I suspect that the interpreter is in the process of exiting and cleaning up the gh_manager object at the same time that the GUI thread is trying to use graphics objects that belong to the gh_manager.

If so, then I believe this is a symptom of the problem that I was trying to describe during our last developer meeting.  I think the solution is to either do a better job of locking threads while using graphics objects or to make graphics objects use copy-on-write semantics so that they can't be modified in one thread while being used in another.

John W. Eaton <jwe>
Project Administrator
Fri 24 Jul 2020 07:57:34 PM UTC, comment #4: 

comment #3:

> Does the attached change make a difference?
>
> If it does: Similar constructs are used all over the place in graphics.cc. Maybe all of those dynamic_casts should be evaluated whether they are save.
>
> (file #49540)


I get this build error that it couldn't convert base_ax_props to bool:

../libinterp/corefcn/graphics.cc: In member function ‘bool patch::properties::get_do_lighting() const’:
../libinterp/corefcn/graphics.cc:9625:7: error: could not convert ‘base_ax_props’ from ‘base_properties’ to ‘bool’
9625 |   if (base_ax_props)
      |       ^~~~~~~~~~~~~
      |       |
      |       base_properties
make[2]: *** [Makefile:18933: libinterp/corefcn/libcorefcn_la-graphics.lo] Error 1

Anonymous
Fri 24 Jul 2020 07:31:51 AM UTC, comment #3: 

Does the attached change make a difference?

If it does: Similar constructs are used all over the place in graphics.cc. Maybe all of those dynamic_casts should be evaluated whether they are save.

(file #49540)

Markus Mützel <mmuetzel>
Project Member
Fri 24 Jul 2020 12:33:20 AM UTC, comment #2: 

Was finally able to get a backtrace.  See below

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007fd35daee8b1 in __GI_abort () at abort.c:79
#2  0x00007fd35e143957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007fd35e149ae6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007fd35e149b21 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007fd35e149d54 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007fd35e148a82 in __cxa_bad_cast () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007fd360585331 in patch::properties::get_do_lighting (this=0x7fd32a507e30)
    at libinterp/corefcn/graphics.cc:9624
#8  0x00007fd360426521 in octave::opengl_renderer::draw_patch (this=0x56013ae2c9a0, props=...)
    at libinterp/corefcn/gl-render.cc:3204
#9  0x00007fd3604121cf in octave::opengl_renderer::draw (this=0x56013ae2c9a0, go=...,
    toplevel=true) at libinterp/corefcn/gl-render.cc:736
#10 0x00007fd36041da60 in octave::opengl_renderer::draw_axes_children (this=0x56013ae2c9a0,
    props=...) at libinterp/corefcn/gl-render.cc:2256
#11 0x00007fd36041e2b2 in octave::opengl_renderer::draw_axes (this=0x56013ae2c9a0, props=...)
    at libinterp/corefcn/gl-render.cc:2344
#12 0x00007fd360411fbc in octave::opengl_renderer::draw (this=0x56013ae2c9a0, go=...,
    toplevel=false) at libinterp/corefcn/gl-render.cc:730
#13 0x00007fd36042dc0f in octave::opengl_renderer::draw (this=0x56013ae2c9a0, hlist=...,
    toplevel=false) at libinterp/corefcn/gl-render.cc:4080
#14 0x00007fd3604131da in octave::opengl_renderer::draw_figure (this=0x56013ae2c9a0, props=...)
    at libinterp/corefcn/gl-render.cc:797
#15 0x00007fd360411f0b in octave::opengl_renderer::draw (this=0x56013ae2c9a0, go=...,
    toplevel=true) at libinterp/corefcn/gl-render.cc:728
#16 0x00007fd360fee780 in QtHandles::GLCanvas::draw (this=0x56013ae2c910, gh=...)
    at libgui/graphics/GLCanvas.cc:87
#17 0x00007fd360fd66f4 in QtHandles::Canvas::canvasPaintEvent (this=0x56013ae2c940)
    at libgui/graphics/Canvas.cc:284
#18 0x00007fd360fefbdc in QtHandles::GLCanvas::paintGL (this=0x56013ae2c910)
    at libgui/graphics/GLCanvas.cc:241
#19 0x00007fd35c4f987d in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007fd35c4d9048 in QWidget::event(QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007fd35c49a83c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
#22 0x00007fd35c4a2104 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007fd3610d4788 in octave::octave_qapplication::notify (this=0x5601392e30c0, receiver=0x56013ae2c910, ev=0x7ffd4b17c8e0)
    at libgui/src/octave-qobject.cc:132
#24 0x00007fd35b71c8d8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#25 0x00007fd35c4d219a in QWidgetPrivate::sendPaintEvent(QRegion const&) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007fd35c4d275a in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007fd35c4d33c0 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007fd35c4d2366 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007fd35c4d33c0 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#30 0x00007fd35c4d3549 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#31 0x00007fd35c4d3549 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#32 0x00007fd35c4d3549 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#33 0x00007fd35c4d2366 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#34 0x00007fd35c4a9dfe in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#35 0x00007fd35c4aa0a5 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#36 0x00007fd35c4c167f in QWidgetPrivate::syncBackingStore() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#37 0x00007fd35c4d91b8 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#38 0x00007fd35c5ecc6b in QMainWindow::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#39 0x00007fd360fee0b3 in QtHandles::FigureWindowBase::event (this=0x56013b7a9100, evt=0x56013c0bdcc0) at libgui/graphics/FigureWindow.h:36
#40 0x00007fd35c49a83c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#41 0x00007fd35c4a2104 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#42 0x00007fd3610d4788 in octave::octave_qapplication::notify (this=0x5601392e30c0, receiver=0x56013b7a9100, ev=0x56013c0bdcc0)
    at libgui/src/octave-qobject.cc:132
#43 0x00007fd35b71c8d8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#44 0x00007fd35b71f04d in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#45 0x00007fd35b776263 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#46 0x00007fd353f6a417 in g_main_context_dispatch () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#47 0x00007fd353f6a650 in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#48 0x00007fd353f6a6dc in g_main_context_iteration () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#49 0x00007fd35b77588f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#50 0x00007fd35b71a90a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#51 0x00007fd35b7239b4 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#52 0x00007fd3610d526d in octave::base_qobject::exec (this=0x7ffd4b17ddf0) at libgui/src/octave-qobject.cc:271
#53 0x00007fd3610e2fc6 in octave::qt_application::execute (this=0x7ffd4b17df70) at libgui/src/qt-application.cc:73
#54 0x0000560137b178a1 in main (argc=3, argv=0x7ffd4b17e278) at src/main-gui.cc:106

The trouble seems to be the dynamic cast in this code

bool
patch::properties::get_do_lighting (void) const
{
  gh_manager& gh_mgr
    = octave::__get_gh_manager__ ("patch::properties::get_do_lighting");

  graphics_object go = gh_mgr.get_object (get___myhandle__ ());

  axes::properties& ax_props = dynamic_cast<axes::properties&>
    (go.get_ancestor ("axes").get_properties ());

  return (ax_props.get_num_lights () > 0);
}

Rik <rik5>
Project Administrator
Fri 24 Jul 2020 12:18:35 AM UTC, comment #1: 

Confirmed.  This worked if I used run-octave from a build directory, but failed if I installed Octave and then called the resulting installed binary.  I named the file tst_segfault.m and called with

octave-7.0.0 -f tst_segfault.m

The -f switch was to make sure there were no local customizations which might be interfering.

Rik <rik5>
Project Administrator
Thu 23 Jul 2020 10:23:14 PM UTC, original submission:  

GNU Octave Version: 7.0.0 (hg id: 5b1143d1d74b)

This bug report is to report a repeatable segfault in certain conditions. This is specific to invoking the file as "octave foo.m" from the bash prompt (or from a shell script) and does not happen when invoking foo.m from within the Octave command prompt. It looks like Octave exits before the graphics objects are cleaned up.

Code:

% mytest.m
n = 6;
A = (rand(n,n,n) > 0.5);

# the following function can be in a standalone file too. the bug still happens.
function voxel2 (pos, sz = [1 1 1], color = [0.8 0.8 0.8], alpha = 0.2)
  verts = (dec2bin(0:7)=='1') .* sz + pos;
  faces = [1 2 4 3; 5 6 8 7; 1 3 7 5; 2 4 8 6; 1 2 7 5; 3 4 8 7]; # the 6 faces of the cube in cyclic order
  patch ("Faces",faces, "Vertices",verts, "facecolor",color, "facealpha",alpha);
endfunction

for i = 1:10
  # the bug does not happen if this loop executes 7 times or fewer. 8 times or more it is repeatable.
  # in production code, matrix A changes for each iteration but for showing this bug it's been frozen
  figure(i); hold on; axis equal; axis off; view(135, atan(1/sqrt(2))*180/pi);
  for p = 1:n
    for q = 1:n
      for r = 1:n
        if (A(p,q,r))
          voxel2 ([p q r]);
        endif
      endfor
    endfor
  endfor
  # saveas (gcf, sprintf ("test%02d.png", i)); # this has been commented out for speeding up bug test execution
endfor

# if calling this script as "octave mytest.m" then segfault / abort occurs here during cleaning up and exiting

Observed output from the bash prompt, after drawing the figure windows:

$ octave mytest.m
warning: base_graphics_object::get_properties: invalid graphics object
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
fatal: caught signal Aborted -- stopping myself...
Aborted (core dumped)

Anonymous

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #49670:  tst_segfault.m added by rik5 (991B - text/x-matlab)
file #49665:  tst_segfault2.m added by rik5 (1KiB - text/x-matlab)
file #49664:  bt.txt added by hg200 (16KiB - text/plain)
file #49644:  tst_spy.m added by None (747B - text/x-objcsrc)
file #49645:  match9.mat added by None (6KiB - application/octet-stream)
file #49540:  bug58814_bad_cast.patch added by mmuetzel (1KiB - 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 hg200 (Updated the item)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by mmuetzel (Updated the item)
  • -email is unavailable- added by rik5 (Posted a comment)
  •  

    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 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    05:08 jwe StatusConfirmed => Ready For Test
    00:18 rik5 Attached File- => Added tst_segfault.m, #49670
    2020-08-13 jwe Attached File- => Added interp-shutdown-reorder-diffs-2.txt, #49669
    2020-08-13 rik5 Attached File- => Added tst_segfault2.m, #49665
    2020-08-13 hg200 Attached File- => Added bt.txt, #49664
    2020-08-13 jwe Attached File- => Added interp-shutdown-reorder-diffs.txt, #49663
    2020-08-09 None Attached File- => Added tst_spy.m, #49644
        Attached File- => Added match9.mat, #49645
    2020-07-24 mmuetzel Attached File- => Added bug58814_bad_cast.patch, #49540
    2020-07-24 rik5 StatusNone => Confirmed

    Back to the top


    Powered by Savane 3.5