Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo


Segfault with SDL

  • Phil Reynolds
    Phil Reynolds

    I have had to upgrade my kernel recently to get proper support for my sound card, and have, as a result, had to switch my X graphics driver to nouveau. I am not sure how relevant either of those two points is, but ever since, I have been unable to use fuse compiled with sdl on the affected machine - I get a segmentation fault. It does not affect the gtk version.

    I tried compiling from trunk revision 4553 - no change in the effect.

    The strace output is quite large and I have therefore pasted it at http://paste.debian.net/144699/

    If someone could please check and advise, that would be much appreciated.

  • You could try running it with valgrind or under gdb - a stack trace would probably be more informative than the strace initally.

  • Phil Reynolds
    Phil Reynolds

    It starts OK with -no-full-screen, but full screen is what I want it for. gdb repeatedly shows these lines in the stack trace:

    #2194 0x0000000000428c8a in sdldisplay_find_best_fullscreen_scaler ()
        at sdldisplay.c:300
    #2195 sdldisplay_load_gfx_mode () at sdldisplay.c:331
    #2196 0x0000000000428faa in uidisplay_hotswap_gfx_mode () at sdldisplay.c:393

    I suspect that it's having problems with this due to nouveau…

  • That is a lot of frames in the stack trace. If there is an oddity about the fullscreen modes reported by the X11 driver that may lead to odd behaviour of the fullscreen resolution selection code.

    It might be interesting to look at the output from running after applying the following patch:
    Index: ui/sdl/sdldisplay.c
    -- ui/sdl/sdldisplay.c (revision 4553)
    +++ ui/sdl/sdldisplay.c (working copy)
    @@ -222,6 +222,7 @@
       /* Check if there are any modes available, or if our resolution is restricted
          at all */
       if( modes == (SDL_Rect **) 0 || modes == (SDL_Rect **) -1 ){
    +    fprintf(stderr, "No modes\n");
         /* Just try whatever we have and see what happens */
         max_fullscreen_height = 480;
         min_fullscreen_height = 240;
    @@ -231,6 +232,7 @@

         /* Record the smallest supported fullscreen software mode */
         for( i=0; modes_; ++i ) {
    +      fprintf(stderr, "Modes %dx%d\n", modes->w, modes->h);
           min_fullscreen_height = modes->h;

  • Phil Reynolds
    Phil Reynolds

    Managed to decipher the patch - looks like some _ were getting dropped…

    Modes 1920x1200 appears before the segfault.

  • SDL API says about SDL_ListModes: The array is not guaranteed to be sorted in any particular order.

    Which make this chunk of code suspicious:

    for( i=0; modes[i]; ++i ) {
      min_fullscreen_height = modes[i]->h;

    What are the order of your modes?

  • Phil Reynolds
    Phil Reynolds

    1920x1200 is the sole mode present.

  • Only one scaler is odd. Fuse seems to miss a lower mode (e.g., 320x240 or 640x480). What modes does xrandr print?

    With 1920x1200 fuse call find_best_fullscreen_scaler which check different scalers which call find_best_fullscreen_scaler again, and so on.

    Maybe this dirty hack could help you:

  • Phil Reynolds
    Phil Reynolds

    Well, it doesn't crash now. It produces an image surrounded by a large amount of black on all sides - whereas before, I could actually get it to fill the vertical.

    xrandr output:

    xrandr: Failed to get size of gamma for output default
    Screen 0: minimum 1920 x 1200, current 1920 x 1200, maximum 1920 x 1200
    default connected 1920x1200+0+0 0mm x 0mm
       1920x1200       0.0*

  • A 3x scaler could give you up to 960x720, which is far from 1920x1200.

    The main problem here is how to change your sole resolution to a lower one.

  • What the SDL UI is trying to do here is to find a mode that covers at least half of the available height of the screen.

    The failure that happens in this particular case is that it gets into a loop where trying to select a scaler to see what its height will work out to be ends up recursively getting into the fullscreen mode selector routine. It seems to be triggered in situations where the only video mode is a large one like the reported 1920x1200. What should be happening is a 3x mode is supposed to be selected which would give a 960x720 mode within the 1920x1200 display which is still a bit small but better than nothing.

    I think that the recursive call into sdldisplay_find_best_fullscreen_scaler() needs to be removed to properly fix the crash but that the only real solution to supporting the increasingly large displays available is to use a scalable output like OpenGL. I think the same issue is relevant for all the other non-SDL UIs where Fuse can end up as a small window in the screen.

  • Phil Reynolds
    Phil Reynolds

    I may well be going back to nvidia drivers soon, due to other things that don't work well in full screen on nouveau, but I remain interested in this just in case the time ever comes that I can get by completely with nouveau.

  • I can't test this as SDL fullscreen seems to be broken on my OS but I wonder if the following patch would help? The aim is to prevent the search for an acceptable fullscreen mode becoming recursive:

    Index: ui/sdl/sdldisplay.c
    --- ui/sdl/sdldisplay.c (revision 4595)
    +++ ui/sdl/sdldisplay.c (working copy)
    @@ -286,11 +289,14 @@
     sdldisplay_find_best_fullscreen_scaler( void )
       static int windowed_scaler = -1;
    +  static int searching_fullscreen_scaler = 0;
       /* Make sure we have at least more than half of the screen covered in
          fullscreen to avoid the "postage stamp" on machines that don't support
          320x240 anymore e.g. Mac notebooks */
       if( settings_current.full_screen ) {
    +    if( searching_fullscreen_scaler ) return;
    +    searching_fullscreen_scaler = 1;
         int i = 0;
         while( i < SCALER_NUM &&
                ( image_height*sdldisplay_current_size <= min_fullscreen_height/2 ||
    @@ -307,6 +313,7 @@
             sdldisplay_current_size = scaler_get_scaling_factor( current_scaler );
    +    searching_fullscreen_scaler = 0;
       } else {
         if( windowed_scaler != -1 ) {
           scaler_select_scaler( windowed_scaler );
  • Seems good to me. It's harmless in a well configured xorg. Stops recursion when trying to force a sole mode of 1900x1200, but I can't set it because my screen don't support such high mode.

  • Thanks for the feedback, I've committed the change in revision 4615.