libs-gui icon indicating copy to clipboard operation
libs-gui copied to clipboard

Segmentation Fault with autohidesScrollers = YES

Open optimisme opened this issue 2 years ago • 5 comments

Maybe my source is totally wrong, but I have been trying to fix this behabiour for days and looking at the stack trace I amb begining to think this is a bug from the libraries.

Looks like there is a recursive cycle in the stack trace, and appears to be caused by an interaction between NSClipView and NSScrollView.

This is the GDB output causing Segmentation Fault:

#596 0x0000fffff7c79e34 in -[NSScrollView reflectScrolledClipView:] (self=0xaaaaab5c6068, _cmd=<optimized out>, 
    aClipView=<optimized out>) at NSScrollView.m:908
#597 0x0000fffff7b3a304 in -[NSClipView setFrame:] (self=0xaaaaab5cbee8, _cmd=<optimized out>, rect=...) at NSClipView.m:570
#598 0x0000fffff7c7b360 in -[NSScrollView tile] (self=<optimized out>, _cmd=<optimized out>) at NSScrollView.m:1303
#599 0x0000fffff7c79d10 in -[NSScrollView reflectScrolledClipView:] (self=0xaaaaab5c6068, _cmd=<optimized out>, 
    aClipView=<optimized out>) at NSScrollView.m:895
#600 0x0000fffff7b3a304 in -[NSClipView setFrame:] (self=0xaaaaab5cbee8, _cmd=<optimized out>, rect=...) at NSClipView.m:570
#601 0x0000fffff7c7b360 in -[NSScrollView tile] (self=<optimized out>, _cmd=<optimized out>) at NSScrollView.m:1303

Looking at NSClipView.m and NSScrollView.m they seem to trigger a series of calls that eventually loop back recursively, leading to an infinite loop?

The only way for me to reproduce this bug, is with a window containing scroll bar, and calling the 'setFrame' of the scroll bar on every window size change.

The window resize must be done very fast until it chrashes.

I attach a video of the application crashing, and the source of the application itself.

https://github.com/gnustep/libs-gui/assets/7429620/6da5005c-3281-47ce-ba5f-49b0a0ec2745

test-bug.zip

optimisme avatar Dec 28 '23 22:12 optimisme

Looking at your stack trace and the code I would say that you run into a condition where the horizontal scroller gets turned off and on. And this somehow results in it being reversed again. I am still unsure how this could happen and confused because there aren't any scrollers visible in your video. Is this behaviour reproducible with the standard theme of GNUstep and can you also recreate it with one of the normal GNUstep applications?

fredkiefer avatar Dec 28 '23 22:12 fredkiefer

Maybe I have to open another bug, trying things, ..., I see the horizontal bar even if I set self.hasHorizontalScroller = NO;

It does not crash on macOS, I really think that should be controlled from GNUStep itself.

Another thing I noticed is that it only happens with 'diagonal' window resizing. I can't make it crash if I only resize the window horizontally or vertically.

The gdb output allways tells the same:

    at NSScrollView.m:1303
#416 0x0000fffff7c79e34 in -[NSScrollView reflectScrolledClipView:] (self=0xaaaaab5986a8, 
    _cmd=<optimized out>, aClipView=<optimized out>) at NSScrollView.m:908
#417 0x0000fffff7b3a304 in -[NSClipView setFrame:] (self=0xaaaaab59e528, _cmd=<optimized out>, rect=...)
    at NSClipView.m:570
#418 0x0000fffff7c7b360 in -[NSScrollView tile] (self=<optimized out>, _cmd=<optimized out>)
    at NSScrollView.m:1303
#419 0x0000fffff7c79d10 in -[NSScrollView reflectScrolledClipView:] (self=0xaaaaab5986a8, 
    _cmd=<optimized out>, aClipView=<optimized out>) at NSScrollView.m:895
#420 0x0000fffff7b3a304 in -[NSClipView setFrame:] (self=0xaaaaab59e528, _cmd=<optimized out>, rect=...)
    at NSClipView.m:570
Until it crashes, the 'bucle' is:
    NSScrollView.m 895 > [self setHasHorizontalScroller: YES];   
    NSClipView.m 570 > [super setFrameSize: aSize];
    NSScrollView.m:1303 > [_contentView setFrame: contentRect];
    NSScrollView.m 908 > [_horizScroller setEnabled: NO];
    NSClipView.m 570 > [super setFrameSize: aSize];
    NSScrollView.m:1303 > [_contentView setFrame: contentRect];
    NSScrollView.m 895 > [self setHasHorizontalScroller: YES];  
    and repeat ... 

optimisme avatar Dec 29 '23 19:12 optimisme

The scroller gets displayed because of the autohides property. In the current GNUstep code this automatically displays a scroller when it is needed and hides it again, when not needed. This behaviour might be different from the one on macOS.

What I don't understand is how disabling the scroller could result in the need for exactly this scroller. Removing the scroller should leave more space not less. Here the values of the frame size might help.

fredkiefer avatar Dec 30 '23 16:12 fredkiefer

Ok, after more testing this is the situation:

  • autohidesScrollers = YES; produces the random segmentation fault when rescaling the window continuously/insistently
  • autohidesScrollers = YES; and hasHorizontalScroller = NO; shows the horizontal scroll even if not desired

I changed the title of this bug to reflect the fact that 'autohidesScrollers = YES;' is the responsible of this 'Segmentation fault'

optimisme avatar Dec 31 '23 09:12 optimisme

By chance, I've obtained a version of the example that fails directly upon startup. The problem is related to 'autohidesScrollers = YES;' and the size of the NSScrollView object.

In this new example 'test-bug2.zip', the following files can be modified for testing:

In the 'VTScroll.m' file, changing 'autohidesScrollers' YES/NO makes the program fail or work (if windowHeight is set to 600).

When 'autohideScrollers' is set to YES in the 'VTScroll.m' file. The 'AppDelegate.m' file, allows to change the value of the 'windowHeight' variable to make the program fail or work. In this case, the values that produce the 'Segmentation fault' are those where 'windowHeight' is between [589, 607] both included."

test-bug2.zip

optimisme avatar Jan 02 '24 08:01 optimisme