kodi-game / game.libretro.snes9x

Snes9X GameClient for XBMC
https://github.com/libretro/snes9x
3 stars 7 forks source link

Snes9x core crash #2

Open fetzerch opened 8 years ago

fetzerch commented 8 years ago

I've seen some crashes with heap corruption warnings when using the Snes9x core. The crash seems to happen either when starting a game or when stopping it (due to a detected memory corruption in the next call to malloc or free). It happens with some games and is always reproducible.

*** Error in `/home/fetzerch/develop/kodi/kodi/kodi.bin': free(): invalid next size (normal)

Valgrind log:

Invalid write of size 1
  in yuv2planeX_8_c in /home/fetzerch/develop/kodi/kodi/tools/depends/target/ffmpeg/ffmpeg-2.6.4-Isengard/libswscale/output.c:264
  1: yuv2planeX_8_c in /home/fetzerch/develop/kodi/kodi/tools/depends/target/ffmpeg/ffmpeg-2.6.4-Isengard/libswscale/output.c:264
  2: swscale in /home/fetzerch/develop/kodi/kodi/tools/depends/target/ffmpeg/ffmpeg-2.6.4-Isengard/libswscale/swscale.c:590
  3: sws_scale in /home/fetzerch/develop/kodi/kodi/tools/depends/target/ffmpeg/ffmpeg-2.6.4-Isengard/libswscale/swscale.c:1088
  4: CRetroPlayerVideo::ColorspaceConversion(unsigned char const*, unsigned int, unsigned int, unsigned int, DVDVideoPicture&) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayerVideo.cpp:192
  5: CRetroPlayerVideo::VideoFrame(unsigned char const*, unsigned int, unsigned int, unsigned int, AVPixelFormat) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayerVideo.cpp:82
  6: CRetroPlayer::VideoFrame(unsigned char const*, unsigned int, unsigned int, unsigned int, AVPixelFormat) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayer.h:130
  7: ADDON::CAddonCallbacksGame::VideoFrame(void*, unsigned char const*, unsigned int, unsigned int, unsigned int, GAME_RENDER_FORMAT) in /home/fetzerch/develop/kodi/kodi/xbmc/addons/AddonCallbacksGame.cpp:132
  8: GAME_video_frame in /home/fetzerch/develop/kodi/kodi/lib/addons/library.kodi.game/libKODI_game.cpp:69
  9: CHelper_libKODI_game::VideoFrame(unsigned char const*, unsigned int, unsigned int, unsigned int, GAME_RENDER_FORMAT) in /home/fetzerch/develop/kodi/binary-addons/build/depends/include/kodi/libKODI_game.h:127
  10: LIBRETRO::CFrontendBridge::VideoRefresh(void const*, unsigned int, unsigned int, unsigned long) in /home/fetzerch/develop/kodi/binary-addons/build/game.libretro/src/FrontendBridge.cpp:69
  11: S9xDeinitUpdate(int, int) in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/libretro/libretro.cpp:942
  12: S9xEndScreenRefresh() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/gfx.cpp:436
  13: S9xDoHEventProcessing() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/cpuexec.cpp:475
  14: OpC8X0() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/cpuops.cpp:1746
  15: S9xMainLoop() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/cpuexec.cpp:308
  16: retro_run in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/libretro/libretro.cpp:808
  17: FrameEvent in /home/fetzerch/develop/kodi/binary-addons/build/game.libretro/src/client.cpp:345
  18: GAME::CGameClient::RunFrame() in /home/fetzerch/develop/kodi/kodi/xbmc/games/addons/GameClient.cpp:574
  19: CRetroPlayer::Process() in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayer.cpp:224
  20: CThread::Action() in /home/fetzerch/develop/kodi/kodi/xbmc/threads/Thread.cpp:221
  21: CThread::staticThread(void*) in /home/fetzerch/develop/kodi/kodi/xbmc/threads/Thread.cpp:131
  22: start_thread in /build/buildd/glibc-2.21/nptl/pthread_create.c:333
  23: clone in /build/buildd/glibc-2.21/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:109
Address 0x2d83a380 is 0 bytes after a block of size 91,648 alloc'd  1: operator new[](unsigned long) in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
  2: CDVDCodecUtils::AllocatePicture(int, int) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp:58
  3: CRetroPlayerVideo::Configure(unsigned int, unsigned int, AVPixelFormat) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayerVideo.cpp:161
  4: CRetroPlayerVideo::VideoFrame(unsigned char const*, unsigned int, unsigned int, unsigned int, AVPixelFormat) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayerVideo.cpp:80
  5: CRetroPlayer::VideoFrame(unsigned char const*, unsigned int, unsigned int, unsigned int, AVPixelFormat) in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayer.h:130
  6: ADDON::CAddonCallbacksGame::VideoFrame(void*, unsigned char const*, unsigned int, unsigned int, unsigned int, GAME_RENDER_FORMAT) in /home/fetzerch/develop/kodi/kodi/xbmc/addons/AddonCallbacksGame.cpp:132
  7: GAME_video_frame in /home/fetzerch/develop/kodi/kodi/lib/addons/library.kodi.game/libKODI_game.cpp:69
  8: CHelper_libKODI_game::VideoFrame(unsigned char const*, unsigned int, unsigned int, unsigned int, GAME_RENDER_FORMAT) in /home/fetzerch/develop/kodi/binary-addons/build/depends/include/kodi/libKODI_game.h:127
  9: LIBRETRO::CFrontendBridge::VideoRefresh(void const*, unsigned int, unsigned int, unsigned long) in /home/fetzerch/develop/kodi/binary-addons/build/game.libretro/src/FrontendBridge.cpp:69
  10: S9xDeinitUpdate(int, int) in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/libretro/libretro.cpp:942
  11: S9xEndScreenRefresh() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/gfx.cpp:436
  12: S9xDoHEventProcessing() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/cpuexec.cpp:475
  13: OpC8X0() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/cpuops.cpp:1746
  14: S9xMainLoop() in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/cpuexec.cpp:308
  15: retro_run in /home/fetzerch/develop/kodi/game.libretro.snes9x-build/build/snes9x/src/snes9x/libretro/libretro.cpp:808
  16: FrameEvent in /home/fetzerch/develop/kodi/binary-addons/build/game.libretro/src/client.cpp:345
  17: GAME::CGameClient::RunFrame() in /home/fetzerch/develop/kodi/kodi/xbmc/games/addons/GameClient.cpp:574
  18: CRetroPlayer::Process() in /home/fetzerch/develop/kodi/kodi/xbmc/cores/RetroPlayer/RetroPlayer.cpp:224
  19: CThread::Action() in /home/fetzerch/develop/kodi/kodi/xbmc/threads/Thread.cpp:221
  20: CThread::staticThread(void*) in /home/fetzerch/develop/kodi/kodi/xbmc/threads/Thread.cpp:131
  21: start_thread in /build/buildd/glibc-2.21/nptl/pthread_create.c:333
  22: clone in /build/buildd/glibc-2.21/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:109
fetzerch commented 8 years ago

@garbear: I've spent some hours to look into the bug (especially now that also people in the forums have confirmed crashes in snes9x and snes9x-next). Unfortunately I don't know ffmpeg or the video player and techniques behind it good enough to figure out what is wrong. Could you please have a look if you have time? Or is there any ffmpeg expert in the team who could help?

CDVDCodecUtils::AllocatePicture:57 allocates a data buffer on the heap to store video frames in:

int totalsize = (iWidth * iHeight) + size * 2;
uint8_t* data = new uint8_t[totalsize];

For a Super Mario World rom, I get the following values: height=224, width=256, totalsize=86016, format=AV_PIX_FMT_RGB565LE.

In ColorspaceConversion (passing on to ffmpeg) some 'magic' happens and writes 1byte too much into that buffer and breaks the heap memory (which leads into the crash on the next malloc/free call).

I can reproduce the same crash (with same valgrind log) also in snes9x-next.

Any help is much appreciated. Thanks, Christian

garbear commented 8 years ago

For Super Mario World (U) [!].smc I get the following values: height=239, width=256, size=15232, totalsize=91648. Are you testing a non-US version? Either way, I can't figure out what's going on.

Once my input stuff is merged, I'm going to rewrite RetroPlayer based on the new VideoPlayer work. This code will be affected, so I'll do some more digging if the problem persists after the rewrite.

fetzerch commented 8 years ago

Ah sry, yeah I tested with Super Mario World (E) (V1.1) [!].smc. Could you reproduce it or is the US version working fine? I've seen the crash with quite a few roms. Thx for looking into it. It clearly better do debug it after the rewrite.

garbear commented 8 years ago

The US version crashes too (works for Beetle bSNES I think). I'll let you know when I dive in and figure out what's wrong. If you figure out anything in the meantime, lmk