Opened 10 months ago

Closed 10 months ago

Last modified 10 months ago

#12852 closed defect (fixed)

CGE2: Random crash with sound thread accessing freed memory

Reported by: criezy Owned by: criezy
Priority: high Component: --Unset--
Version: Keywords:
Cc: Game:

Description

This can easily be reproduced when enabling address sanitizer (otherwise the freed memory access might not cause a crash and not be noticed). Just start the game and wait until it crashes (it can take a couple of minutes).

The asan report is:

=================================================================
==31428==ERROR: AddressSanitizer: heap-use-after-free on address 0x00015ae5222c at pc 0x000115c0519c bp 0x00016dacfff0 sp 0x00016dacf7a8
READ of size 512 at 0x00015ae5222c thread T8
    #0 0x115c05198 in __asan_memcpy+0x1a4 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3d198)
    #1 0x10beac7d0 in Common::MemoryReadStream::read(void*, unsigned int) stream.cpp:103
    #2 0x10beadc6c in Common::SubReadStream::read(void*, unsigned int) stream.cpp:232
    #3 0x10bc81b80 in Audio::RawStream<1, true, false>::fillBuffer(int) raw.cpp:140
    #4 0x10bc80dc0 in Audio::RawStream<1, true, false>::readBuffer(short*, int) raw.cpp:99
    #5 0x10bc0ae60 in Audio::LinearRateConverter<false, false>::flow(Audio::AudioStream&, short*, unsigned int, unsigned short, unsigned short) rate.cpp:237
    #6 0x10bbf14bc in Audio::Channel::mix(short*, unsigned int) mixer.cpp:645
    #7 0x10bbf0e34 in Audio::MixerImpl::mixCallback(unsigned char*, unsigned int) mixer.cpp:298
    #8 0x10ae7bb64 in SdlMixerManager::callbackHandler(unsigned char*, int) sdl-mixer.cpp:189
    #9 0x10ae7ba6c in SdlMixerManager::sdlCallback(void*, unsigned char*, int) sdl-mixer.cpp:196
    #10 0x1154fc624 in outputCallback+0x178 (libSDL2-2.0.0.dylib:arm64+0xb0624)
    #11 0x19726b3ec in ClientAudioQueue::CallOutputCallback(AudioQueueBuffer*)+0x12c (AudioToolbox:arm64e+0x443ec)
    #12 0x197253e74 in ClientAudioQueue::FetchAndDeliverPendingCallbacks(unsigned int)+0x2d0 (AudioToolbox:arm64e+0x2ce74)
    #13 0x197253b1c in _XCallbackNotificationsAvailable+0xcc (AudioToolbox:arm64e+0x2cb1c)
    #14 0x196202ccc in mshMIGPerform+0x100 (libAudioToolboxUtility.dylib:arm64e+0x11ccc)
    #15 0x18b17f314 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__+0x38 (CoreFoundation:arm64e+0x85314)
    #16 0x18b17f1d0 in __CFRunLoopDoSource1+0x250 (CoreFoundation:arm64e+0x851d0)
    #17 0x18b17d650 in __CFRunLoopRun+0x940 (CoreFoundation:arm64e+0x83650)
    #18 0x18b17c594 in CFRunLoopRunSpecific+0x254 (CoreFoundation:arm64e+0x82594)
    #19 0x1154fc1b4 in audioqueue_thread+0x474 (libSDL2-2.0.0.dylib:arm64+0xb01b4)
    #20 0x1154a1430 in SDL_RunThread+0x2c (libSDL2-2.0.0.dylib:arm64+0x55430)
    #21 0x1154f1b58 in RunThread+0x8 (libSDL2-2.0.0.dylib:arm64+0xa5b58)
    #22 0x18b07f874 in _pthread_start+0x13c (libsystem_pthread.dylib:arm64e+0x7874)
    #23 0x18b07a5dc in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x25dc)

0x00015ae5222c is located 48684 bytes inside of 52187-byte region [0x00015ae46400,0x00015ae52fdb)
freed by thread T0 here:
    #0 0x115c072b4 in wrap_free+0x98 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3f2b4)
    #1 0x10412ea64 in CGE2::DataCk::~DataCk() sound.cpp:44
    #2 0x10412ea94 in CGE2::DataCk::~DataCk() sound.cpp:43
    #3 0x104130708 in CGE2::Fx::clear() sound.cpp:143
    #4 0x10412f394 in CGE2::Fx::load(int, int) sound.cpp:164
    #5 0x1041591f0 in CGE2::CGE2Engine::snSound(CGE2::Sprite*, int, Audio::Mixer::SoundType) snail.cpp:610
    #6 0x104153178 in CGE2::CommandHandler::runCommand() snail.cpp:244
    #7 0x1041376e0 in CGE2::CGE2Engine::mainLoop() cge2_main.cpp:529
    #8 0x10413a38c in CGE2::CGE2Engine::runGame() cge2_main.cpp:635
    #9 0x10413be3c in CGE2::CGE2Engine::cge2_main() cge2_main.cpp:752
    #10 0x104111c0c in CGE2::CGE2Engine::run() cge2.cpp:193
    #11 0x10288f46c in runGame(Plugin const*, Plugin const*, OSystem&, Common::String const&) main.cpp:311
    #12 0x10288a530 in scummvm_main main.cpp:618
    #13 0x102881bac in main macosx-main.cpp:45
    #14 0x18b09d42c in start+0x0 (libdyld.dylib:arm64e+0x1842c)

previously allocated by thread T0 here:
    #0 0x115c07178 in wrap_malloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3f178)
    #1 0x104130b0c in CGE2::Fx::loadWave(CGE2::EncryptedStream*) sound.cpp:169
    #2 0x10412f3a0 in CGE2::Fx::load(int, int) sound.cpp:165
    #3 0x1041591f0 in CGE2::CGE2Engine::snSound(CGE2::Sprite*, int, Audio::Mixer::SoundType) snail.cpp:610
    #4 0x104153178 in CGE2::CommandHandler::runCommand() snail.cpp:244
    #5 0x1041376e0 in CGE2::CGE2Engine::mainLoop() cge2_main.cpp:529
    #6 0x10413a38c in CGE2::CGE2Engine::runGame() cge2_main.cpp:635
    #7 0x10413be3c in CGE2::CGE2Engine::cge2_main() cge2_main.cpp:752
    #8 0x104111c0c in CGE2::CGE2Engine::run() cge2.cpp:193
    #9 0x10288f46c in runGame(Plugin const*, Plugin const*, OSystem&, Common::String const&) main.cpp:311
    #10 0x10288a530 in scummvm_main main.cpp:618
    #11 0x102881bac in main macosx-main.cpp:45
    #12 0x18b09d42c in start+0x0 (libdyld.dylib:arm64e+0x1842c)

Thread T8 created by T0 here:
    #0 0x115c01560 in wrap_pthread_create+0x54 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x39560)
    #1 0x1154f1b10 in SDL_SYS_CreateThread+0x98 (libSDL2-2.0.0.dylib:arm64+0xa5b10)
    #2 0x1154a1550 in SDL_CreateThreadWithStackSize_REAL+0x6c (libSDL2-2.0.0.dylib:arm64+0x55550)
    #3 0x1154fb8e8 in COREAUDIO_OpenDevice+0x284 (libSDL2-2.0.0.dylib:arm64+0xaf8e8)
    #4 0x115457264 in open_audio_device+0x568 (libSDL2-2.0.0.dylib:arm64+0xb264)
    #5 0x115456c9c in SDL_OpenAudio_REAL+0x6c (libSDL2-2.0.0.dylib:arm64+0xac9c)
    #6 0x10ae7a74c in SdlMixerManager::init() sdl-mixer.cpp:73
    #7 0x10286acc0 in OSystem_SDL::initBackend() sdl.cpp:284
    #8 0x10287e308 in OSystem_POSIX::initBackend() posix.cpp:93
    #9 0x102882b74 in OSystem_MacOSX::initBackend() macosx.cpp:113
    #10 0x102889eb0 in scummvm_main main.cpp:503
    #11 0x102881bac in main macosx-main.cpp:45
    #12 0x18b09d42c in start+0x0 (libdyld.dylib:arm64e+0x1842c)

Change History (4)

comment:1 by criezy, 10 months ago

I forgot to indicate this is on a M1 mac with current master (18ee050adf2).

comment:2 by NMIError, 10 months ago

Owner: set to criezy
Resolution: fixed
Status: newclosed

I just pushed a commit which should fix this problem. I cannot reproduce it myself, because I can not get the address sanitizer working.
Could you please retest to check if the deallocated memory access no longer occurs?

comment:3 by criezy, 10 months ago

Thanks!
I tested with your changes and it seems the issue is indeed fixed.

comment:4 by NMIError, 10 months ago

Great, thanks for the feedback!

Note: See TracTickets for help on using tickets.