Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RetroArch segfaults when loading cores from command line when no content is specified #4493

Closed
orbea opened this issue Jan 24, 2017 · 14 comments

Comments

@orbea
Copy link
Contributor

orbea commented Jan 24, 2017

Description

RetroArch will segfault when a core is loaded from the command line with -L while failing to specify any content. It seems to affect all cores with content while no content cores such as 2048 work fine.

Expected behavior

RetroArch should fail safely if no content is found and maybe print a message explaining that no content was found.

Actual behavior

This is the backtrace I receive when tested with snes9x-libretro.

Thread 1 "retroarch" received signal SIGSEGV, Segmentation fault.
0x00007fffeb273b68 in retro_load_game (game=0x0) at ../libretro/libretro.cpp:483
483	   if(game->data == NULL && game->size == 0 && game->path != NULL)
(gdb) bt
#0  0x00007fffeb273b68 in retro_load_game (game=0x0)
    at ../libretro/libretro.cpp:483
#1  0x000000000041257b in core_load_game (load_info=0x7fffffffc6e0)
    at core_impl.c:288
#2  0x00000000004294b2 in content_file_load (info=0x9e54a0, content=0x934c30, 
    content_ctx=0x7fffffffc7a0, error_string=0x7fffffffc798, special=0x0)
    at tasks/task_content.c:575
#3  0x0000000000429a84 in content_file_init (content_ctx=0x7fffffffc7a0, 
    error_string=0x7fffffffc798) at tasks/task_content.c:750
#4  0x000000000042a8ba in content_init () at tasks/task_content.c:1420
#5  0x0000000000419fa0 in event_init_content () at command.c:1338
#6  0x000000000041a131 in command_event_init_core (data=
    0x8c6688 <current_core_type>) at command.c:1403
#7  0x000000000041b9c5 in command_event (cmd=CMD_EVENT_CORE_INIT, 
    data=0x8c6688 <current_core_type>) at command.c:2236
#8  0x0000000000414a54 in retroarch_main_init (argc=3, argv=0x7fffffffe1f8)
    at retroarch.c:1075
#9  0x0000000000428b37 in content_load (info=0x7fffffffe0c0)
    at tasks/task_content.c:278
#10 0x0000000000429cc4 in task_load_content (content_info=0x7fffffffe0c0, 
    content_ctx=0x7fffffffe030, launched_from_menu=false, mode=
    CONTENT_MODE_LOAD_FROM_CLI, error_string=0x7fffffffe028)
    at tasks/task_content.c:821
#11 0x000000000042a4ca in task_push_content_load_default (core_path=0x0, 
    fullpath=0x0, content_info=0x7fffffffe0c0, type=CORE_TYPE_PLAIN, mode=
    CONTENT_MODE_LOAD_FROM_CLI, cb=0x0, user_data=0x0)
    at tasks/task_content.c:1239
#12 0x00000000004113af in rarch_main (argc=3, argv=0x7fffffffe1f8, data=0x0)
    at frontend/frontend.c:113
#13 0x0000000000411440 in main (argc=3, argv=0x7fffffffe1f8)
    at frontend/frontend.c:148

Full GDB log - http://pastebin.com/dJv1VT6y

Steps to reproduce the bug

  1. Start a core from the command line without any content: retroarch -L /path/to/core_libretro.so
  2. Segmentation Fault...

Bisect Results

This occurs with 1.3.6 too and I have not tried any earlier commits.

Version/Commit

snes9x-libretro-2017.01.23_690d475_master-x86_64-1_git
RetroArch-2017.01.24_7aaf19381_master-x86_64-1_git

Environment information

  • OS: Slackware64-current

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@inactive123
Copy link
Contributor

Can't reproduce this at all following your step 1 in 'Steps to reproduce the bug'. Please be more specific so that I can actually reproduce this with (say) the SNES9x core.

Also, this is not necessarily a RetroArch issue, but more a core-by-core issue. The issue there is that we don't check if 'game' is NULL there. If it's NULL, it should return false inside retro_load_game, that would allow RetroArch to cleanly handle the error. So it's a core bug.

@orbea
Copy link
Contributor Author

orbea commented Jan 24, 2017

Its not a core problem as every core does it (Except content-less cores like 2048). Unless you are saying all of the cores are broken?

All I have to do to reproduce that is that command, for example...

$ retroarch -L /usr/lib64/libretro/glupen64_libretro.so
Segmentation fault

$ retroarch -L /usr/lib64/libretro/snes9x_libretro.so 
Sound buffer size: 128160 (32040 samples)
Segmentation fault

$ retroarch -L /usr/lib64/libretro/vecx_libretro.so 
Segmentation fault

$ retroarch -L /usr/lib64/libretro/mame2000_libretro.so 
Segmentation fault

$ retroarch -L /usr/lib64/libretro/mednafen_psx_hw_libretro.so 
Segmentation fault

$ retroarch -L /usr/lib64/libretro/reicast_libretro.so 
Segmentation fault

The backtrace was arbitrarily done with snes9x-libretro, if any other core might produce a more helpful backtrace I can make one.

I also asked a friend who was running a RetroArch commit from November and he was also able to reproduce it.

@inactive123
Copy link
Contributor

It is a core problem.

Reason - snes9x no longer crashes like that anymore after I updated it. Go ahead, do a git pull on the repo, recompile it and try again. It will now cleanly exit and return you back to the command prompt.

@orbea
Copy link
Contributor Author

orbea commented Jan 24, 2017

Well since you put it that way I have to agree you are right, thanks! snes9x no longer segfaults now.

I guess this can be addressed in each core as its encountered and this issue can be closed.

For reference.
libretro/snes9x2002@f50d04d

@orbea orbea closed this as completed Jan 24, 2017
@inactive123
Copy link
Contributor

Can you make a listing of each core this happens with so I can go down the list and get most of them fixed?

@orbea
Copy link
Contributor Author

orbea commented Jan 24, 2017

Sure, I will compile one by the latest tomorrow.

@orbea
Copy link
Contributor Author

orbea commented Jan 24, 2017

@twinaphex Here is a list of cores that segfaults when started with no content for me.

bnes_libretro.so
Segmentation fault

bsnes_mercury_accuracy_libretro.so
Segmentation fault

gambatte_libretro.so
Segmentation fault

hatari_libretro.so
Retro SYSTEM_DIRECTORY /media/data/home/games/bios
Retro SAVE_DIRECTORY /media/data/home/games/bios
Retro CONTENT_DIRECTORY /home/orbea/.config/retroarch/downloads
[libretro-test]: Got size: 640 x 480.
Segmentation fault

lutro_libretro.so
Segmentation fault

mame2010_libretro.so
value: enabled
value: enabled
value: enabled
value: enabled
value: disabled
Segmentation fault

mame2014_libretro.so
Segmentation fault

mame_libretro.so
Segmentation fault

mednafen_psx_libretro.so
Segmentation fault

nxengine_libretro.so
Segmentation fault

@Alcaro
Copy link
Contributor

Alcaro commented Jan 24, 2017

Isn't the point of libretro to remain backwards and forwards compatible forever, including old cores that assume the retro_load_game argument can be dereferenced? Are we going to break that promise?

@orbea
Copy link
Contributor Author

orbea commented Jan 24, 2017

I'm going to reopen this issue until a solution can be agreed upon. See this PR. libretro/bsnes-mercury#30

@orbea orbea reopened this Jan 24, 2017
@Alcaro
Copy link
Contributor

Alcaro commented Jan 24, 2017

Let's take the discussion here.

Per my post in that PR, retro_load_game(NULL) is not supported by that core, or most other cores. Any reasonable definition of "unsupported" means "the callee can assume this never happens", as evidenced by the number of cores you're "fixing".

If we're suddenly defining what this specific unsupported scenario does, then it is by definition supported. Making a previously-unsupported scenario supported, without there being properly documented fallbacks in place for old cores/fronts, is a backwards incompatible change and requires incrementing RETRO_API_VERSION. Unless you're doing that, I will not tolerate unexplained, undocumented, forwards incompatible changes in an API documented as stable.

If you want to increment that integer, go ahead. Otherwise, the only correct solution is not calling retro_load_game(NULL) unless SET_SUPPORT_NO_GAME is used; even with your proposed changes, the frontend can already know that it will just return false, which is a waste of time.

@orbea
Copy link
Contributor Author

orbea commented Jan 25, 2017

@Alcaro When you have a chance can you look at the other linked issues to make sure they are all core bugs?

@Alcaro
Copy link
Contributor

Alcaro commented Jan 26, 2017

No, two of those are still frontend bugs; rarch is calling retro_unload_game despite retro_load_game not returning true. That's better handled in #4493.

Reicast looks like it's mixing up retro_unload_game and retro_deinit in some strange way, which is a core bug.

@orbea
Copy link
Contributor Author

orbea commented Mar 24, 2017

The issues that still occur and seem like frontend issues are...

libretro/nxengine-libretro#29
libretro/beetle-psx-libretro#152

orbea pushed a commit to orbea/libretro-lutro that referenced this issue Aug 22, 2018
My understanding is this is a combination of a frontend bug in
RetroArch and a core bug in lutro. RetroArch attempts to unload
content even when it was never loaded and lutro is deiniting content
in retro_deinit instead of retro_unload_core.

Please see:

libretro/RetroArch#4493
libretro/RetroArch#7102

Note that this fix in lutro is enough without also requiring the fix
in RetroArch which is needed for other cores.
orbea pushed a commit to orbea/hatari that referenced this issue Aug 22, 2018
My understanding is this is a combination of a frontend bug in
RetroArch and a core bug in hatari. RetroArch attempts to unload
content even when it was never loaded and hatari is deiniting
content in retro_deinit instead of retro_unload_core.

Please see:

libretro/RetroArch#4493
libretro/RetroArch#7102

Note that this fix in hatari also requires the fix in RetroArch.

This also removes the executive permissions of 0755 from
Makefile.libretro to the correct permissions of 0644.
orbea pushed a commit to orbea/hatari that referenced this issue Aug 22, 2018
Please see:

libretro/RetroArch#4493
libretro/RetroArch#7102

Note this does not require changes in RetroArch.

This also removes the executive permissions of 0755 from
Makefile.libretro to the correct permissions of 0644.
orbea pushed a commit to orbea/hatari that referenced this issue Aug 22, 2018
Note this does not require changes in RetroArch.

Please see:

libretro/RetroArch#4493
libretro/RetroArch#7102

This also removes the executive permissions of 0755 from
Makefile.libretro to the correct permissions of 0644.
orbea pushed a commit to orbea/hatari that referenced this issue Aug 22, 2018
Note this does not require changes in RetroArch.

Please see:

libretro/RetroArch#4493
libretro/RetroArch#7102
@orbea
Copy link
Contributor Author

orbea commented Dec 16, 2018

I guess this can be closed now.

@orbea orbea closed this as completed Dec 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants