Menu

#1845 wxt window crashes app when resized by dragging

None
closed-out-of-date
nobody
None
2024-07-03
2016-08-21
Dan Sebald
No

Latest development version, linux Mint/Cinnamon, WXT version 3.0.0-2.

Here is the result of a dragging the lower right corner of a WXT plot to resize. Resizing works for a while but when the scale is about half the original size, gnuplot segfaults:

gnuplot> set term wxt
Terminal type set to 'wxt'
Options are '0 enhanced'
gnuplot> plot sin(x)
gnuplot> *** Error in `gnuplot': double free or corruption (fasttop): 0x0000000001435cd0 ***
Aborted

Here is going back to 01/01/16

gnuplot> set term wxt
Terminal type set to 'wxt'
Options are '0 enhanced'
gnuplot> plot sin(x)
gnuplot> **
Gdk:ERROR:/build/gtk+2.0-3ongxb/gtk+2.0-2.24.23/gdk/gdkregion-generic.c:337:miSetExtents: assertion failed: (pExtents->y1 < pExtents->y2)
Aborted

I've gone back further in time, but at some point it no longer compiles, so I'm assuming this is a Qt5 issue that has never been worked out.

Discussion

1 2 > >> (Page 1 of 2)
  • Dan Sebald

    Dan Sebald - 2016-08-21

    Sorry, the Qt5 doesn't make sense--multi-tasking debugging on two different projects here...

    I managed to narrow things down just slightly, but this is a tricky one as the wxt GUI seems to crash randomly within a certain range of executing code. I put in some fprintf(stderr,) statements and found it wasn't always crashing at the same line. But it always seemed to be within the same function, wxt_text(). So what I did was place a

    #if 0
    #endif
    

    around everything within that routine. Sure enough, no crash. Of course, it affects the plot, all-black at first, but on resizing it is fine.

     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    It's this line within wxt_text():

    @@ -2083,7 +2103,7 @@
    
        /* raise the window, depending on the user's choice */
        wxt_MutexGuiEnter();
    -   wxt_raise_window(wxt_current_window, false);
    +// wxt_raise_window(wxt_current_window, false);
        wxt_MutexGuiLeave();
    
     #ifdef USE_MOUSE
    

    And within wxt_raise_window() it appears to be either one of these two calls crashes:

    @@ -3204,8 +3230,8 @@
            // leave it alone if it is maximized.
            if (window->frame->IsIconized())
     #endif
    -       window->frame->Restore();
    -       window->frame->Raise();
    +//     window->frame->Restore();
    +//     window->frame->Raise();
    

    Raise() goes back to the wxWindow object. Restore(), I can't seem to find that in the WX documentation.

    Could be a WX bug in the particular version I have.

     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    This looks to be a duplicate. I searched for the error message and found

    https://sourceforge.net/p/gnuplot/bugs/1592/

    I'll look through that.

     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    When I set the wxt terminal to "noraise", both my example and the example from the above link seem to work fine:

    set term wxt noraise
    i=1; while (i<100) {plot i*x title "".i; i=i+1; pause 0.1}
    
     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    I've configured with

    TERMLIBS="-lX11" /home/sebald/gnuplot/gnuplot/gnuplot/configure --with-wx-single-threaded
    

    and both examples above worked without "noraise", i.e., I can tell that the plot window is raising with each plot.

    Could it be that these

           window->frame->Restore();
           window->frame->Raise();
    

    are queued somehow and grab ahold of the mutex and restore/raise/redraw is active when

        /* Inform gnuplot that we have finished plotting */
        wxt_exec_event(GE_plotdone, 0, 0, 0, 0, wxt_window_number );
    

    indicates plotting is done? That is, gnuplot continues on doing another draw (because resizing queues up many redraws, and the example given above with looping also does successive redraws).

     
  • Ethan Merritt

    Ethan Merritt - 2016-08-21

    I can't reproduce any of this, but logically it is a waste of time to execute "raise window" on every refresh while you are resizing the window. What happens if you temporarily disable raise? I.e.

    --- old/src/wxterminal/wxt_gui.cpp  2016-07-31 07:57:56.754252999 -0700
    +++ new/src/wxterminal/wxt_gui.cpp  2016-08-21 08:42:17.557699118 -0700
    @@ -1062,7 +1062,10 @@ void wxtPanel::OnSize( wxSizeEvent& even
            /* create a new cairo context of the good size */
            wxt_cairo_create_context();
            /* redraw the plot with the new scaling */
    +       int save_raise_state = wxt_raise;
    +       wxt_raise = no;
                     wxt_cairo_refresh();
    +       wxt_raise = save_raise_state;
     }
    
     #ifdef USE_MOUSE
    
     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    This doesn't change the behavior. With "raise" still active. There is still a crash.

    What is the wxt_cairo_refresh()? Is that recalling the cairo/wx function calls from some list? Or is it re-executing the gnuplot terminal calls? It's in the function wxt_text() where if I comment out the call to wxt_raise_window(). Is wxt_cairo_refresh() initiating a call to wxt_text() either directly or indirectly?

    Actually, I think it is an alternate path that wxt_text() gets called because I comment out the modification of the plot:

        /* create a new cairo context of the good size */
    //  wxt_cairo_create_context();
        /* redraw the plot with the new scaling */
        int save_raise_state = wxt_raise;
        wxt_raise = no;
    //  wxt_cairo_refresh();
        wxt_raise = save_raise_state;
    

    and still the "raise" scenario causes a crash.

    When I do the above, the plot memory is all scrambled, understandably. (If I bring the lower-right corner back to its original location, the pixels all line up again.) But, what I do notice is that when I drag the window corner, the footer text is not scrambled and is changing. Is that where the wxt_text() is getting called? Those values have to be coming from the core, I'm guessing, because they represent coordinates on the plot space. But of course, these too don't seem worth updating when sizing because they make no sense. In fact, after resizing, when I move the mouse inside the non-footer region again the coordinates immediately jump from something bogus to sane values.

     

    Last edit: Dan Sebald 2016-08-21
    • Ethan Merritt

      Ethan Merritt - 2016-08-23

      The cursor position text is written by an entirely separate routine from normal text. For the wxt terminal it is this routine in wxt_gui.cpp

      / Write a string to the clipboard /
      void wxt_set_clipboard(const char s[])
      {...}

      If you know a resize operation is in progress, you could just have that routine return without doing anything. But I'm not sure that's easy to detect unambiguously.

       

      Last edit: Ethan Merritt 2016-08-23
    • Dan Sebald

      Dan Sebald - 2016-08-23

      Perhaps you were thinking of

      /* Display temporary text, after
       * erasing any temporary text displayed previously at this location.
       * The int determines where: 0=statusline, 1,2: at corners of zoom
       * box, with \r separating text above and below the point. */
      void wxt_put_tmptext(int n, const char str[])
      {
      

      I started following your suggestion wxt_set_clipboard() but that didn't seem to go anywhere.

      I looked in mouse.c and commented out this line:

          if (term->put_tmptext) {
      //  (term->put_tmptext) (0, s0);
          }
      

      and the text no longer appears in the status line. Unfortunately, I'd have to go back somehow to the original issue by removing the GTK3 development libraries (but those don't always unextract the requirements, so who knows?).

      But it might be worth this. It could be that there is no mutex on the portion of code writing to the status line--whether that is an issue, I'm not sure. (Or maybe GTK later realized there doesn't need to be a mutex for that and fixed some past bug.) Here's the route:

      1) wxt_put_tmptext(int n, const char str[]) does make use of the mutex, i.e., calls wxt_MutexGuiEnter(). However,

      2) In the case of writing to the status line (i.e., 'n' equals 0), the text isn't written directly but is instead sent via an event, wxStatusTextEvent.

      3) That wxStatusTextEvent might be processed later than the routine wxt_put_tmptext() lets go of the mutex.

      4) If so, then the routine executed in response to the event,

          EVT_COMMAND( wxID_ANY, wxStatusTextEvent, wxtFrame::OnSetStatusText )
      

      calls the wxWidget member function SetStatusText(event.GetString()) without any other lines of code, i.e., no grabbing ahold of the mutex.

      Does that sound like a problem? Should a try getting back to the segfaulting version and explore?

       
      • Ethan Merritt

        Ethan Merritt - 2016-08-23

        It sounds like the mutex is correct. The point of the mutex is so that the main thread (i.e. gnuplot proper) can make a change in something being accessed by the graphics thread without messing it up my changing something currently in use. The graphics thread doesn't need a mutex to change it's own stuff. And vice versa.

        Anyhow, if upgrading to wxgtk 3.0.2 fixes things I think the bottom line message is that we should put a warning in the Release Notes and build instructions that wxgtk 3.0.0 is buggy and should be avoided if possible.

         
  • Ethan Merritt

    Ethan Merritt - 2016-08-21

    Oops. I've just notice that the very first thing you posted was

    WXT version 3.0.0-2.

    I never got gnuplot to work with wxt 3.0.0, too many bugs in the library. Both runtime and compile time errors. It didn't start working until 3.0.2. The wxt 3.0.0 bugginess was acknowledged in the release notes for 3.0.2 (" Upgrading to it is strongly recommended for all users of the previous 3.0.x release as it bring a lot of bug fixes"). So I'm inclined to say you're dealing with a wxgtk bug and nothing you do in the gnuplot code will fix it.

     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    May have found a separate bug (see below), but making note here for reference:

    1) I first investigated whether using "m" in the plot window to turn off the footer would do anything. It seemed to solve the problem, until I wildly moved around the window corner and then I got a crash again...but it wasn't the same kind of error message as reported above. So, I went on with the intent of upgrading to wxWidgets 3.0.2.

    2) I downloaded wxWidgets 3.0.2 and set about building. The configure script wanted the development version of GTK. I installed the libdev version of the GTK 3 and ran configure. Seemed fine...but then out of curiosity...

    3) I went back to reconfigure, clean and rebuild gnuplot after having installed the libdev GTK3 and all the dependency libraries that went along with it. After this, wxt terminal didn't crash on resizing...until I wildly moved around the window corner.

    The error message I get when wildly moving about the lower-right corner to resize seems to be a gnuplot error, not a wx/GTK error. And it might have to do with shrinking the window so small that the plot inherently flips the min/max of an axis. See if you can replicate this:

    gnuplot> set term wxt
    Terminal type set to 'wxt'
    Options are '0 enhanced'
    gnuplot> plot sin(x)
    [move the lower right corner around for a while and then make the window near zero width and continue to move corner about]
    gnuplot>          warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
             warning: Warning - difficulty fitting plot titles into key
    *** Error in `gnuplot': double free or corruption (fasttop): 0x00000000019c4700 ***
    Aborted
    

    To be clear, I have to move the window size so small that not only does the above error message appear, but the x/y-axis min/max range inverts (watch real closely when the plot is tiny and one can see this happen).

     
  • Dan Sebald

    Dan Sebald - 2016-08-21

    A segfault still happens when turning off the key and shrinking plot very small:

    gnuplot> set term wxt
    Terminal type set to 'wxt'
    Options are '0 enhanced'
    gnuplot> set key off
    gnuplot> plot sin(x)
    gnuplot> Segmentation fault
    
     
  • Ethan Merritt

    Ethan Merritt - 2016-08-21

    I can't reproduce that. On my machine the wxt plot window cannot be resized below a minimum of about 100x50 pixels. That is small enough to generate the "difficulty fitting ..." errors but not small enough to flip the orientation. I don't know where that minimum size comes from. Does your setup not have a minimum size? I suppose we could add it explicitly to the code somewhere.

     
    • Dan Sebald

      Dan Sebald - 2016-08-21

      No minimum size constraint for wx/GTK here. (You're using KDE, which might be the source of the limit.) x11 terminal doesn't have a minimum either...and I noticed there is a bug there too, not a crash bug, but a drawing bug which I will investigate separately and fix. Qt terminal does have a minimum, so maybe that's an example that has the limit done in the terminal driver.

      Sizing is kind of funny in itself. If I do something like:

      set term wxt size 10,10
      set key off
      plot sin(x)
      

      the axes are projected in the direction opposite usual. There must be some formula which subtracts the room left for axis annotation.

       
  • Dan Sebald

    Dan Sebald - 2016-08-24

    After looking at something in X11 that caused problems for small window size where xright < xleft, I've determined that WXT window segfaulting is not connected to the inversion of ytop/ybot or xright/xleft.

    So I looked more closely at the condition that causes the segfault. I don't have to make the window so small that the ytop/ybot invert. Just making it rather small is enough. I wonder if it is the speed of rendering that is the issue. That is, only when the window is small does rescaling lead to a condition where there could be a timing clash.

    Is there a setting to put this one on hiatus? I expect to be upgrading from Mint Rosa to Mint Sarah (or whatever the new name is) fairly soon, but not within months. I expect the newer version to have more up-to-date libraries underneath the Qt and wxWidgets frameworks. If the crash still exists for the more recent stuff, I'll come back to this one.

     
  • Ethan Merritt

    Ethan Merritt - 2016-09-03
    • status: open --> open-postponed
    • Group: -->
    • Priority: -->
     
  • Bastian Märkisch

    FWIW, I am seeing a reproducible crash even for wxGTK 3.0.2 on Ubuntu 16.04 for

    set term wxt; do for [i=1:1000] { clear }
    

    It seems related to a race condition (probably for the GUI mutex) in wxt_raise_window. Number of iterations until it crashes seems random. A work-around is to disable raise-on-replot in the GUI, or to build with --with-wx-single-threaded. The crash also goes away if I comment out the line

    window->frame->Raise();
    

    Crash backtraces show a number of different points of failure. Here a the last gnuplot functions in three successive backtraces, where case 2) seems the most probable:

    1)  0x00000000005247fd in wxt_text () at wxterminal/wxt_gui.cpp:2179
    2) (none :wxAppConsoleBase::MainLoop())
    3)  0x0000000000524821 in wxt_text () at wxterminal/wxt_gui.cpp:2186
    
     
  • Ethan Merritt

    Ethan Merritt - 2016-10-13

    I think I see the fix for Dan's original problem.
    However I have no idea why "clear" would ever fail.
    Does the following fix it for you?

    --- gnuplot/src/wxterminal/wxt_gui.cpp  2016-10-10 14:52:28.483063350 -0700
    +++ gnuplot-cvs/src/wxterminal/wxt_gui.cpp      2016-10-13 14:26:34.592031446 -0700
    @@ -3001,7 +3001,9 @@ void wxtPanel::wxt_cairo_refresh()
                    wxt_cairo_draw_hypertext();
    
     #ifdef IMAGE_SURFACE
    +       command_list_mutex.Lock();
            wxt_cairo_create_bitmap();
    +       command_list_mutex.Unlock();
     #endif /* !have_gtkcairo */
    
            /* draw the pixmap to the screen */
    
     
    • Bastian Märkisch

      No. The problem persists. The command in the loop does not really matter, as long as it is is "simple enough": plot x causes a crash here, too.

       
    • Dan Sebald

      Dan Sebald - 2016-10-14

      I didn't see an improvement either midday Thursday. I was just waiting to see if there was an improvement for Bastian's system in case I had forgotten exactly what the conditions were. Are there anymore similar cases that might need a mutex lock/unlock?

       
  • Ethan Merritt

    Ethan Merritt - 2016-10-13
    • status: open-postponed --> pending-fixed
     
  • Ethan Merritt

    Ethan Merritt - 2016-10-14
    • status: pending-fixed --> open
     
  • Ethan Merritt

    Ethan Merritt - 2016-10-14

    Fooey. I managed to reproduce the original problem (segfault on resize from dragging the mouse), and taking the mutex lock fixed it for me. Dan is probably right that there are other places needing to lock the mutex, but I don't know where they are.

     
  • Dan Sebald

    Dan Sebald - 2016-10-16

    That change may solve something on your system. But the lock in your diff file is around a bitmap routine, but "plot sin(x)" has no bitmap; it's all lines and fonts.

    I have a small clue/test example. I noticed the "test" screen, i.e.,

    > gnuplot
    set term wxt
    test
    

    will not crash with resizing. I can rescale that as small as possible, no crash. It has all sorts of plot elements, so one would think it isn't the rendering portion of the driver that is causing an issue.

    Also, this is not a problem:

    > gnuplot
    set term wxt
    clear
    

    I can resize without problems with the above.

    But the following crashes with scaling:

    set term wxt; unset xtics; unset ytics; unset border; unset key; plot sin(x)
    

    And it requires me to make the window size somewhere near where the internal axes reaches its minimum. I've set the margins to all 0s--still crashes with rescaling.

    I think it has something to do with the computation of the plot borders, the layout somehow.

    I just noticed there is another test screen:

    > gnuplot
    set term wxt
    test palette
    

    does not fail either. I looks like a typical plot to me. So, what is the difference between these test plots and the usual interactive plots?

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.