bugGNU Octave - Bugs: bug #57234, 'dbquit' in graphics system...


bug #57234: 'dbquit' in graphics system callback function can cause segfault

Submitted by:  Guillaume <gyom>
Submitted on:  Thu 14 Nov 2019 11:02:00 AM UTC  
Category:  Interpreter Severity:  3 - Normal
Priority:  3 - Low Item Group:  Segfault, Bus Error, etc.
Status:  Patch Submitted Assigned to:  None
Originator Name:  Guillaume 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)

Thu 19 Dec 2019 05:51:53 PM UTC, comment #16: 

This is not great, but I don't think we should spend excessive programmer time on what amounts to a very small fraction of Octave running time (How much time to people really spend, in the debugger, and then within graphics system callbacks?).  If there is a relatively simple way to plug up the hole and stop segfaults that would be nice, but creating an entire edifice for instantiating multiple readline instances doesn't sound like a good use of time.

Rik <rik5>
Project Administrator
Thu 19 Dec 2019 05:44:18 PM UTC, comment #15: 

I think I can prevent the crash, but properly handling input inside a callback function is going to be difficult.

As far as I can tell, calling readline recursively is not going to work.  Looking at the code in main_window::run_file_in_terminal, it seems that someone must have already recognized this problem.  There, an attempt is made to jump out of the readline input loop and execute code as a function call, followed by restoring any pending input the next time readline is called.  But even that is only a partial solution since the internal readline state won't be saved and restored properly if it is called again for a separate input sequence (debugging vs. the normal command prompt).  There are functions in readline for saving and restoring part of the internal state (rl_save_state and rl_restore_state) but they appear to be incomplete and not fully functional.

I just don't see a way to fix this problem without fixing readline so that multiple instances can be created and used simultaneously.  Then the debugger (or anything that wants to get user input) could create a new readline object, use that, and then restore/redisplay the previous readline prompt when finished.

John W. Eaton <jwe>
Project Administrator
Fri 13 Dec 2019 04:54:01 PM UTC, comment #14: 

Pantxo, your patch from comment #13 is a change in the right direction but there is a simpler way.  In the catch block for the execution_exception, you can just write

catch (octave::execution_exception& e)
    m_interpreter.handle_exception (e);

There is a lot more going on in this bug.  The reason we see the error

 terminate called after throwing an instance of 'octave::quit_debug_exception'

is that in the debugger::repl function the quitting_debugger function throws that exception outside of any try/catch block that can catch it.  Fixing that by moving the quitting_debugger call inside the try/catch block that immediately follows the call leads to an infinite loop because the execution state remains unchanged.  Fixing that mostly works but leads to a strange error  message about "dbquit may only be used when debugging" when the user presses ENTER.  That's happening because we are making recursive calls to readline without saving and restoring readline's internal state.

I'm working on fixes for all these issues but it may take a little time.  With some luck, maybe I won't break anything else!

John W. Eaton <jwe>
Project Administrator
Wed 11 Dec 2019 08:35:05 PM UTC, comment #13: 

Here is the patch I have been using to show the full stack trace, as if the error hadn't been caught.

It is not exactly what Matlab does, i.e. the stack trace is populated and the error message is the original one, not the "execution error in graphics callback function" which doesn't look very useful.

(file #48047)

Pantxo Diribarne <pantxo>
Project Member
Wed 11 Dec 2019 02:38:47 PM UTC, comment #12: 

@Pantxo: Yes, you get the error message and the full stack trace:

>> testme
>> Unrecognized function or variable 'throw_an_error'.

Error in testme>clbk (line 7)
  throw_an_error ();

Error while evaluating UIControl Callback.

>> lasterr

ans =

    'Error while evaluating UIControl Callback.'

>> lasterror

ans =

  struct with fields:

       message: 'Error while evaluating UIControl Callback.'
    identifier: 'MATLAB:UndefinedFunction'
         stack: [0x1 struct]

Guillaume <gyom>
Wed 11 Dec 2019 02:28:39 PM UTC, comment #11: 

@Guillaume: About the original issue in comment #0, does Matlab show error messages in graphics callbacks? Does it show the stack trace? Does "lasterr" contain the error message or is the error somewhat cast into a warning?

Pantxo Diribarne <pantxo>
Project Member
Sat 07 Dec 2019 03:43:15 PM UTC, comment #10: 

Here's another way to demonstrate the problem.  Define the following function (can be at the command line):

function fff ()
  remove_input_event_hook ("fff");
  error ("foobar!");

then execute

debug_on_error (true);
add_input_event_hook ("fff");

that should put you at a debug prompt.  Then enter a dbquit command and Octave will crash with

terminate called after throwing an instance of 'octave::quit_debug_exception'

I'm working on a fix so that quit_debug_exception is handled properly when it is thrown from a function that is executed in the readline event loop.

John W. Eaton <jwe>
Project Administrator
Fri 06 Dec 2019 10:51:32 PM UTC, comment #9: 

Oh, I was going by the statement in comment #4 that said it was sufficient to just press enter at the prompt.  Will try to duplicate the other problem(s) now.

John W. Eaton <jwe>
Project Administrator
Fri 06 Dec 2019 10:43:32 PM UTC, comment #8: 

Yes sorry, the bisection in comment #4 was done using code from bug #57354 and pressing <return>. This is closer to bug #57244, which is fixed by the patch.

If run the code from comment #3 I observe the very same as described by Rik, including the strange "pseudo-debug mode" after dbcont or dbnext.

Pantxo Diribarne <pantxo>
Project Member
Fri 06 Dec 2019 10:14:25 PM UTC, comment #7: 

The patch works fine.  But, it solves the issue over in bug #57244 (Return at debug prompt causes segfault) rather than this one.

Rik <rik5>
Project Administrator
Fri 06 Dec 2019 09:41:03 PM UTC, comment #6: 

The attached change seems to fix the problem for me.  If it works for you and there are no additional problems I will push a proper changeset.

(file #48020)

John W. Eaton <jwe>
Project Administrator
Fri 06 Dec 2019 07:46:44 AM UTC, comment #5: 

I'll try to take a look at this problem.

John W. Eaton <jwe>
Project Administrator
Wed 04 Dec 2019 08:45:21 PM UTC, comment #4: 

As Guillaume said in bug #27544, <return> (instead of dbquit) is enough to trigger the crash.
I bisected and found that the revision that introduced this issue is

changeset:   27504:7a31b25e3252
user:        John W. Eaton <jwe@octave.org>
summary:     use shared_ptr for storing classdef and statement_list objects in parser

Adding jwe to the recepients of this report.

Pantxo Diribarne <pantxo>
Project Member
Fri 15 Nov 2019 11:03:33 PM UTC, comment #3: 

Confirmed.  I've attached an augmented test file called tst_cberr.m shown below.

function tst_cberr ()
  F = figure ();
  uicontrol (F, 'String', 'Button', 'Callback', @clbk1);

function clbk1 (h, e)
  x = pi;
  clbk2 (h, e);

function clbk2 (h, e)
  throw_an_error ();

To reproduce, start Octave and then

debug_on_error (1)
## Click on button in figure window

The dbstack command works for me and shows the chain of clbk1 and clbk2.

The dbquit command produces

terminate called after throwing an instance of 'octave::quit_debug_exception'
fatal: caught signal Aborted -- stopping myself...
Abort (core dumped)

Interestingly, if instead of dbquit, I use dbnext, I get

execution error in graphics callback function

debug> dbwhere
at top level
debug> dbnext
error: dbstep: can only be called in debug mode

The debugger is in a strange state where it is at the top-level, but the "debug>" prompt is still displayed.  Executing another "dbnext" is required to leave this pseudo-debug mode and return to the real Octave prompt.

Rik <rik5>
Project Administrator
Fri 15 Nov 2019 09:51:29 AM UTC, comment #2: 

Ah, sorry, there was a typo in the formatting:

Debugging errors in callbacks is difficult as the call stack is not displayed
and only this error message appears:

execution error in graphics callback function

as, for example, here:

function testme
  F = figure ();
  uicontrol (F, 'String', 'Button', 'Callback', @clbk);

function clbk (h, e)
  throw_an_error ();

then if one use 'dbstop if error', click the button and type 'dbquit', there's a segfault.

Guillaume <gyom>
Thu 14 Nov 2019 08:03:34 PM UTC, comment #1: 

@Guillaume: It seems that your bug report was truncated.  I don't see what the error message is.

Also, do you have an example that can be used for testing?

Rik <rik5>
Project Administrator
Thu 14 Nov 2019 11:02:00 AM UTC, original submission:  

Debugging errors in callbacks is difficult as the call stack is not displayed and only this error message appears:

Guillaume <gyom>


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

Attach Files:

Attached Files
file #48047:  bug#57234_show_stack.patch added by pantxo (2KiB - text/x-patch)
file #48020:  diffs.txt added by jwe (2KiB - text/plain)


Carbon-Copy List
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by pantxo
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by gyom (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 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-04-28 rik5 Dependencies- => bugs #60463 is dependent
    2019-12-31 rik5 Priority5 - Normal => 3 - Low
    2019-12-11 pantxo Attached File- => Added bug#57234_show_stack.patch, #48047
    2019-12-06 jwe Attached File- => Added diffs.txt, #48020
        StatusConfirmed => Patch Submitted
    2019-12-04 pantxo Carbon-Copy- => Added jwe
    2019-12-04 pantxo Dependencies- => bugs #57354 is dependent
    2019-11-15 rik5 StatusNeed Info => Confirmed
        SummaryUse of debugger in callbacks => 'dbquit' in graphics system callback function can cause segfault
    2019-11-14 rik5 StatusNone => Need Info

    Back to the top

    Powered by Savane 3.7