bugGNU Octave - Bugs: bug #44330, Qt toolkit segmentation fault when...

 
 

bug #44330: Qt toolkit segmentation fault when figure opened, closed, and opened again

Submitter:  -X- <jsh>
Submitted:  Sat 21 Feb 2015 01:38:11 AM UTC
   
 
Category:  Plotting with OpenGL Severity:  4 - Important
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sun 16 Apr 2017 01:01:09 AM UTC, comment #30: 

To reconfirm, I do not see the original issue either with or without the backout anymore. However, I do get bug #50801 irrespective of backout (or not).

-X- <jsh>
Fri 14 Apr 2017 01:48:25 PM UTC, comment #29: 

The issue is with the recent snapshots  (at the moment it is

 hg id
d4ef04757ead tip @​)

compiled with (-O2 -fsanitize=undefined):



octave:1> f = figure; c = uicontrol( 'parent', f, 'string', 'button' ); delete(c); delete(f)
octave:2> /usr/include/qt5/QtWidgets/qwidget.h:746:35: runtime error: downcast of address 0x0000010f7b00 which does not point to an object of type 'QWidget'
0x0000010f7b00: note: object is of type 'QObject'
 00 00 00 00  e0 9e 7b a9 bf 7f 00 00  60 ed 11 01 00 00 00 00  b8 6b c6 a9 bf 7f 00 00  00 00 0f 01
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'QObject'
../libgui/graphics/Container.cc:110:67: runtime error: member call on address 0x0000010f7b00 which does not point to an object of type 'QWidget'
0x0000010f7b00: note: object is of type 'QObject'
 00 00 00 00  e0 9e 7b a9 bf 7f 00 00  60 ed 11 01 00 00 00 00  b8 6b c6 a9 bf 7f 00 00  00 00 0f 01
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'QObject'
warning: base_graphics_object::get_properties: invalid graphics object
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted (core dumped)


The qt backend on this particular computer (i7-2600K intel graphics) is all messed
up -- the qt window would not refresh until I do e.g. "print".


​Dmitri.​

Dmitri A. Sergatskov <dasergatskov>
Fri 14 Apr 2017 08:29:17 AM UTC, comment #28: 

@jsh, Dmitri: just to make sure I understand correctly, the segfault you report with the uicontrol test is present with and without the backout right (this is what I understand from bug #50801)? So the original issue here is gone and the new reported issue is not solved by the cset from comment #20. If so could we backout the cset from comment #20 and find another fix?

Pantxo Diribarne <pantxo>
Group Member
Thu 13 Apr 2017 06:22:28 AM UTC, comment #27: 

If I add a short pause() between delete(c) and delete(f) then it works fine:


 octave:1> f = figure; c = uicontrol( 'parent', f, 'string', 'button' ); delete(c); pause(0.1); delete(f)
octave:2>

But for short pause it still crashes:

octave:1> f = figure; c = uicontrol( 'parent', f, 'string', 'button' ); delete(c); pause(0.01); delete(f)
octave:2> warning: base_graphics_object::get_properties: invalid graphics object
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted (core dumped)


Dmitri.

Dmitri A. Sergatskov <dasergatskov>
Thu 13 Apr 2017 06:05:28 AM UTC, comment #26: 

Here is backtrace:

(gdb) backtrace
#0  0x00007fffeb27f7bb in raise () at /lib64/libc.so.6
#1  0x00007fffeb2815d1 in abort () at /lib64/libc.so.6
#2  0x00007fffebae2fc5 in __gnu_cxx::__verbose_terminate_handler() () at /lib64/libstdc++.so.6
#3  0x00007fffebae0bb6 in  () at /lib64/libstdc++.so.6
#4  0x00007fffebadfab9 in  () at /lib64/libstdc++.so.6
#5  0x00007fffebae04a8 in __gxx_personality_v0 () at /lib64/libstdc++.so.6
#6  0x00007fffeb8480e3 in  () at /lib64/libgcc_s.so.1
#7  0x00007fffeb84890e in _Unwind_Resume () at /lib64/libgcc_s.so.1
#8  0x00007ffff517a525 in QObjectPrivate::setParent_helper(QObject*) () at /lib64/libQt5Core.so.5
#9  0x00007ffff517a996 in QObject::~QObject() () at /lib64/libQt5Core.so.5
#10 0x00007ffff59e166c in QWidget::~QWidget() () at /lib64/libQt5Widgets.so.5
#11 0x00007ffff5b1e6d9 in QPushButton::~QPushButton() () at /lib64/libQt5Widgets.so.5
#12 0x00007ffff7a53cb2 in QtHandles::Object::finalize() (this=0xa60220) at ../libgui/graphics/Object.cc:140
#13 0x00007ffff7a53a79 in QtHandles::Object::slotFinalize() (this=0xa60220) at ../libgui/graphics/Object.cc:110
#14 0x00007ffff7a11817 in QtHandles::Object::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0xa60220, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0x7fffb44ee780) at libgui/graphics/moc-Object.cc:93
#15 0x00007ffff5174199 in QObject::event(QEvent*) () at /lib64/libQt5Core.so.5
#16 0x00007ffff599ed9c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5
#17 0x00007ffff59a63d4 in QApplication::notify(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5
#18 0x00007ffff514bb8b in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib64/libQt5Core.so.5
#19 0x00007ffff514dd6b in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () at /lib64/libQt5Core.so.5
#20 0x00007ffff519ac73 in postEventSourceDispatch(_GSource*, int ()(void), void*) () at /lib64/libQt5Core.so.5
#21 0x00007fffe7ac31d7 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#22 0x00007fffe7ac3578 in g_main_context_iterate.isra () at /lib64/libglib-2.0.so.0
#23 0x00007fffe7ac360c in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#24 0x00007ffff519acef in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#25 0x00007ffff514ab8a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#26 0x00007ffff51527dc in QCoreApplication::exec() () at /lib64/libQt5Core.so.5
#27 0x00007ffff798e66f in octave::gui_application::execute() (this=0x7fffffffc358) at ../libgui/src/octave-gui.cc:248
#28 0x00000000004016e1 in main(int, char**) (argc=9, argv=0x7fffffffc5f8) at ../src/main-gui.cc:104

Dmitri A. Sergatskov <dasergatskov>
Thu 13 Apr 2017 05:27:59 AM UTC, comment #25: 

That was run-octave --nogui
In the gui version I get
"octave exited with signal 6"

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 13 Apr 2017 05:23:31 AM UTC, comment #24: 

I have the same problem (hg id 77a7f2fecd74 tip @)

octave:1> f = figure; c = uicontrol( 'parent', f, 'string', 'button' ); delete(c), delete(f)
octave:2> warning: base_graphics_object::get_properties: invalid graphics object
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted (core dumped)

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 13 Apr 2017 03:16:20 AM UTC, comment #23: 

Just tested the #22 test script on Windows (10) and there Octave hangs completely, while on Linux I get segfault. Again without the 'string' property all is fine on both Win and Linux.

-X- <jsh>
Thu 13 Apr 2017 02:54:50 AM UTC, comment #22: 

I do not get segfault for the test sequence from comment #21 with the backout anymore, however, I still get segfault with one of the orginal test sequences:


f = figure; c = uicontrol( 'parent', f, 'string', 'button' ); delete(c), delete(f)


which after 1-10 times segfaults, the uicontrol with string property seems critical, since Octave doesn't segfault without it.

-X- <jsh>
Wed 12 Apr 2017 11:32:26 AM UTC, comment #21: 

The cset that fixed this bug also probably introduced bug #44776.

I still can't reproduce the original bug if I backout the cset from comment #20. Do people who were able to confirm this bug still see it with the attached backout?

I tested with the following sequence:

h = figure (); close (h);h = figure (); close (h);  h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h);


(file #40371)

Pantxo Diribarne <pantxo>
Group Member
Wed 18 Mar 2015 02:14:57 PM UTC, comment #20: 
John W. Eaton <jwe>
Group administrator
Wed 18 Mar 2015 01:30:37 AM UTC, comment #19: 

Works for me with a few of the examples that segfaulted before.

Mike Miller <mtmiller>
Group Member
Wed 18 Mar 2015 12:28:06 AM UTC, comment #18: 

I seem to be able to avoid the crash with just the attached change to avoid a redraw when updating the bounding box.



(file #33386)

John W. Eaton <jwe>
Group administrator
Fri 13 Mar 2015 09:03:28 AM UTC, comment #17: 

At least having a way to query from Qt thread whether the interpreter is idle would help. Is it possible to have the interpreter set a boolean variable (e.g. in the octave_qt_link) each time it starts/completes an operation?

We could also use semaphores for critical operations that need to be executed sequentially.

Pantxo Diribarne <pantxo>
Group Member
Thu 12 Mar 2015 09:13:50 PM UTC, comment #16: 

My understanding is that the atomic refcount thing ensures that refcounting is done properly when those objects are copied across threads.

But there are other things that can cause trouble.  For example, you can't ask the interpreter to evaluate a function at an arbitarary time because it could be busy evaluating some other function, and I don't think there is any way for that to be safe.

John W. Eaton <jwe>
Group administrator
Thu 12 Mar 2015 07:03:37 PM UTC, comment #15: 

How does atomic refcounting relate to this discussion?  Is that only protecting data structures against being deleted in either the plotting thread or Octave while the other might be using it?  I suppose if we have atomic access then we could set up a global semaphore to prevent the plotting thread from proceeding until given permission by Octave.  It would be nicer if we didn't have to code that ourselves though.

Rik <rik5>
Group administrator
Thu 12 Mar 2015 06:50:13 PM UTC, comment #14: 

Yes, maybe.

I'm almost certain that the crashes are happening because of threading issues, and that we are calling Octave internals from the graphics thread when it is not safe to do so.  If this wasn't an issue with the original QtHandles code, then maybe there was some change that was made since integrating it with Octave that allows unsafe calls where none were possible before.  If so, we need to know how to avoid doing that.  If it's just that were were lucky before, then we need to rethink the design.

John W. Eaton <jwe>
Group administrator
Thu 12 Mar 2015 06:25:17 PM UTC, comment #13: 

@jwe: Is this something that Michael Goffioul would know since he did the original QtHandles work?

Rik <rik5>
Group administrator
Thu 12 Mar 2015 05:17:56 PM UTC, comment #12: 

Is there some simple change that we can make so that the plotting thread can only handle events when Octave is idle?  I'm not saying that's the ultimate solution, but it would at least test my idea that the problem is related to threading.

John W. Eaton <jwe>
Group administrator
Tue 10 Mar 2015 04:15:18 AM UTC, comment #11: 

Re-running the original example code I now occasionally get more error messages when the segfault occurs.  See below


octave:5> h = figure (); close (h); h = figure ();
octave:6> pure virtual method called
terminate called without an active exception
panic: Aborted -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
Abort


Interestingly, it seems that Octave has returned to the command prompt before something else goes wrong.

More confirmation that there is some sort of race condition, the following code works


h = figure (); close (h); pause (0.1); h = figure ();


But it is possible to make the delay short and then the segmentation fault returns.  For example, a delay of .01 fails for me.

Rik <rik5>
Group administrator
Sun 08 Mar 2015 04:30:17 PM UTC, comment #10: 

I don't know if it is really related, but bug #44463 shows a manifestation of a race condition when using Qt graphics toolkit. Looks like the drawnow function returns while the opengl rendering has not been completed.

Pantxo Diribarne <pantxo>
Group Member
Mon 02 Mar 2015 10:47:50 PM UTC, comment #9: 

Since this works with FLTK, which only processes events when Octave is otherwise idle (or in a safe spot to do so), I think my initial change may actually be in the wrong direction.  I think we may need to limit what the Qt toolkit can do unless Octave is waiting for input.  However, unlike FLTK, the Qt widget thing is running in a separate thread, so it could possibly handle events continuously while readline is active, not just when readline calls the input_event_hook function.

John W. Eaton <jwe>
Group administrator
Mon 02 Mar 2015 10:27:53 PM UTC, comment #8: 

Alas, I see the same behavior as reported in comment #7.  The initial segfault no longer occurs, but the code sequence still generates a segfault.  Adding drawnow() calls in between the figure and reset doesn't help either.  I even tried


h = figure; drawnow; set (h, '__modified__', 'on'); drawnow; __process_graphics_events__ ; reset (h)


but it still segfaults.  Although it does take more than one attempt to get it to segfault.

Rik <rik5>
Group administrator
Mon 02 Mar 2015 02:31:12 AM UTC, comment #7: 

The new patch works for me and the original bug. But


h = figure; reset( h )


still leads to segfault. Oddly enough in my old build I could do these commands twice before segfault. But now with the patch it immediately segfaults.

I'm not sure if its really related but if I play around with uiobjects enough, sooner or later there seems to be a sync problem with the internal graphics handles (see #44339 ).

-X- <jsh>
Sun 01 Mar 2015 02:58:42 PM UTC, comment #6: 

I'm attaching a patch to try.  I'm not sure if it is the right thing to do, but it appears to avoid the problem for me.  I see now other good way to handle this issue, but maybe someone else will have some ideas.

I also don't understand why this isn't an issue with the fltk widgets.  I would expect the close request callback to be processed until after the second call to figure in both cases, and by that point, I'm not sure what will happen since it seems things would be out of order (close was supposed to be called for figure 1, but the second call to figure creates a new figure with handle 1.  Maybe one part of the problem is that we should be using a real handle/pointer internally instead of the integer figure number.  That way, close (h) could look up the real handler/pointer immediately and the callback would operate on that object, not whatever object "1" happens to refer to later.

(file #33219)

John W. Eaton <jwe>
Group administrator
Sun 01 Mar 2015 01:48:34 PM UTC, comment #5: 

For me it crashs with octave GUI and --no-gui (both using qt toolkit)

Anonymous
Sun 01 Mar 2015 06:23:20 AM UTC, comment #4: 

I don't know if this is a helpful clue, but I noticed that


h = figure (); drawnow (); close (h); h = figure ();


does not crash for me.

John W. Eaton <jwe>
Group administrator
Sun 01 Mar 2015 05:13:15 AM UTC, comment #3: 

The sample code segfaults for me every time.  Here is the backtrace:


./run-octave -g -f --no-gui
octave:1> graphics_toolkit ("qt");
octave:2> h = figure (); close (h); h = figure ();

---Type <return> to continue, or q <return> to quit---
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff348aad4 in QWidget::update() () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
(gdb) bt
#0  0x00007ffff348aad4 in QWidget::update() ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#1  0x00007ffff7ae0d2b in QtHandles::Canvas::redraw (this=0x7ef2c0, sync=false)
    at graphics/Canvas.cc:51
#2  0x00007ffff7aed27d in QtHandles::Figure::redraw (this=0x7fa2a0)
    at graphics/Figure.cc:341
#3  0x00007ffff7aefa0b in QtHandles::Figure::updateContainer (this=0x7fa2a0)
    at graphics/Figure.cc:848
#4  0x00007ffff7ad4acc in QtHandles::Figure::qt_static_metacall (_o=0x7fa2a0,
    _c=QMetaObject::InvokeMetaMethod, _id=11, _a=0x7fffd81c3d50)
    at graphics/moc-Figure.cc:86
#5  0x00007ffff2f3f446 in QObject::event(QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#6  0x00007ffff3448894 in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#7  0x00007ffff344d713 in QApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#8  0x00007ffff2f25e9c in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#9  0x00007ffff2f29c6a in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#10 0x00007ffff2f54f93 in ?? () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#11 0x00007fffed933d13 in g_main_context_dispatch ()
   from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#12 0x00007fffed934060 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#13 0x00007fffed934124 in g_main_context_iteration ()
   from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#14 0x00007ffff2f553bf in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#15 0x00007ffff34f0d9e in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#16 0x00007ffff2f24c82 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
    () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#17 0x00007ffff2f24ed7 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#18 0x00007ffff2f29f67 in QCoreApplication::exec() ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#19 0x00007ffff7a77447 in octave_start_gui (argc=10, argv=0x7fffffffca28, start_gui=false)
    at src/octave-gui.cc:203
#20 0x0000000000402dc0 in main (argc=10, argv=0x7fffffffca28) at main-gui.cc:43


Note that this was with the newish CLI interface to the Qt libraries.  When I run in the GUI I don't get a segfault.

Rik <rik5>
Group administrator
Sat 21 Feb 2015 04:02:29 PM UTC, comment #2: 

Hi,

I can't confirm this bug with my current build but I have had segfaults in the past when reseting the visibility of a Qt figure:


h = figure ("visible", "off");
reset (h);


The asynchronous nature of updates in QtHandles make it hard to debug.
Some kind of semaphores (at least for debuging purpose) for update triage between Octave and QtHandles would help.

Pantxo Diribarne <pantxo>
Group Member
Sat 21 Feb 2015 04:06:22 AM UTC, comment #1: 

Thanks for your bug report. Confirmed, the segmentation fault is in the Qt graphics_toolkit library. If "graphics_toolkit fltk" is used instead there is no segfault.

The following is enough to make the segfault occur for me. The commands have to occur on a single line, no return to the prompt to allow background events to be processed. Or the commands have to occur in a single script without any pause between them.


graphics_toolkit ("qt");
h = figure (); close (h); h = figure ();


Mike Miller <mtmiller>
Group Member
Sat 21 Feb 2015 01:38:11 AM UTC, original submission:  

I get about 80% immediate crash probability when running the attached script opening and closing a figure (I failed to isolate the issue to attaching the whole script).

Dev branch running Qt Gui.
System: Linux mint 17
Error message: octave exited with signal 11

-X- <jsh>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #40371:  redraw.patch added by pantxo (697B - text/x-patch)
file #33386:  diffs.txt added by jwe (520B - text/plain)
file #33219:  diffs.txt added by jwe (2KiB - text/plain)
file #33143:  test_octave.m added by jsh (2KiB - 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 dasergatskov (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by jsh (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 12 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-04-12 pantxo Attached File- Added redraw.patch, #40371
    2015-03-18 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
    2015-03-18 jwe Attached File- Added diffs.txt, #33386
    2015-03-10 rik5 StatusPatch Submitted Confirmed
    2015-03-01 jwe Attached File- Added diffs.txt, #33219
        StatusConfirmed Patch Submitted
    2015-02-21 mtmiller CategoryGUI Plotting with OpenGL
        Severity3 - Normal 4 - Important
        StatusNone Confirmed
        Summary80% immediate crash probability when running scrips Qt toolkit segmentation fault when figure opened, closed, and opened again
    2015-02-21 jsh Attached File- Added test_octave.m, #33143

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code