|
Crash in al_destroy_voice() on OS X |
Bruce Pascoe
Member #15,931
April 2015
|
So one of my testers recently uncovered an odd crash: engine(32687,0x102a9e000) malloc: *** error for object 0x101809a00: pointer being freed was not allocated With help from lldb, I was able to get a stack trace, implicating Allegro's AQueue routines: frame #4: 0x00000001000e29c6 liballegro_audio.5.1.dylib`_aqueue_deallocate_voice(voice=0x00000001005359f0) + 70 at aqueue.m:212 209 static void _aqueue_deallocate_voice(ALLEGRO_VOICE *voice) 210 { 211 al_free(voice->extra); -> 212 al_free(silence); 213 voice->extra = NULL; 214 } 215 frame #5: 0x00000001000e1a38 liballegro_audio.5.1.dylib`al_destroy_voice(voice=0x00000001005359f0) + 40 at kcm_voice.c:114 111 ASSERT(al_get_voice_playing(voice) == false); 112 113 /* We do NOT lock the voice mutex when calling this method. */ -> 114 voice->driver->deallocate_voice(voice); 115 al_destroy_mutex(voice->mutex); 116 al_destroy_cond(voice->cond); 117 The entire stack trace: * thread #6: tid = 0x33298d, 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT * frame #0: 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10 frame #1: 0x00007fff92a1c35c libsystem_pthread.dylib`pthread_kill + 92 frame #2: 0x00007fff96f58b1a libsystem_c.dylib`abort + 125 frame #3: 0x00007fff9161707f libsystem_malloc.dylib`free + 411 frame #4: 0x00000001000e29c6 liballegro_audio.5.1.dylib`_aqueue_deallocate_voice(voice=0x00000001005359f0) + 70 at aqueue.m:212 frame #5: 0x00000001000e1a38 liballegro_audio.5.1.dylib`al_destroy_voice(voice=0x00000001005359f0) + 40 at kcm_voice.c:114 frame #6: 0x0000000100164bab liballegro.5.1.dylib`_al_run_destructors(dtors=0x0000000100535980) + 155 at dtor.c:117 frame #7: 0x00000001000d8675 liballegro_audio.5.1.dylib`_al_kcm_shutdown_destructors + 21 at kcm_dtor.c:46 frame #8: 0x00000001000d74e8 liballegro_audio.5.1.dylib`al_uninstall_audio + 24 at audio.c:401 frame #9: 0x0000000100166108 liballegro.5.1.dylib`_al_run_exit_funcs + 136 at exitfunc.c:92 frame #10: 0x000000010016cac5 liballegro.5.1.dylib`al_uninstall_system + 21 at system.c:298 frame #11: 0x00007fff96f59794 libsystem_c.dylib`__cxa_finalize + 164 frame #12: 0x00007fff96f59a4c libsystem_c.dylib`exit + 22 frame #13: 0x00000001001a77be liballegro.5.1.dylib`+[AllegroAppDelegate app_main:] [inlined] call_user_main + 30 at osx_app_delegate.m:214 frame #14: 0x00000001001a77a4 liballegro.5.1.dylib`+[AllegroAppDelegate app_main:](self=<unavailable>, _cmd=<unavailable>, arg=<unavailable>) + 4 at osx_app_delegate.m:225 frame #15: 0x00007fff917d0d8b Foundation`__NSThread__main__ + 1318 frame #16: 0x00007fff92a1b899 libsystem_pthread.dylib`_pthread_body + 138 frame #17: 0x00007fff92a1b72a libsystem_pthread.dylib`_pthread_start + 137 frame #18: 0x00007fff92a1ffc9 libsystem_pthread.dylib`thread_start + 13 Note there is no application code in the callstack, only system calls and Allegro. This happens on shutdown. It's worth noting that I already call al_uninstall_audio() myself. Allegro seems to be calling it again, which I suspect is the cause of the crash.
|
GullRaDriel
Member #3,861
September 2003
|
Did you try to remove that al_uninstall_audio call and see if it's really the culprit ? "Code is like shit - it only smells if it is not yours" |
Bruce Pascoe
Member #15,931
April 2015
|
Actually the plot thickens on this one. Notice how there's no user code on the stack at all? At the point the crash happens, there are still a few more steps in the shutdown process (going by my own console output), and yet here you can see that main() has already returned. I'm completely baffled.
|
Elias
Member #358
May 2000
|
All the atexit() functions are called after main() has returned. -- |
Bruce Pascoe
Member #15,931
April 2015
|
That's the thing though--I have console output for my initialization and shutdown procedures, and at the point this crash happens, main shouldn't have returned yet. That's why I'm confused.
|
Elias
Member #358
May 2000
|
Why do you think it has returned already then? -- |
Bruce Pascoe
Member #15,931
April 2015
|
Look at the callstack above.
|
SiegeLord
Member #7,827
October 2006
|
Wow. Looks like the aqueue driver doesn't support multiple voices at all. I'll investigate if that's an API limitation, and if not, I'll implement it tomorrow. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Bruce Pascoe
Member #15,931
April 2015
|
Is that what's causing the crash, then? Still weird that it returned from main prematurely like that...
|
Elias
Member #358
May 2000
|
What's the point of more than one voice? I never understood that... -- |
Bruce Pascoe
Member #15,931
April 2015
|
One case where it's useful is if you want to output, say, 8- and 16-bit audio in the same app (maybe your game has some sort of retro effect or something), you can't actually create an 8-bit mixer so you need to make the voice 8-bit. In this case you would need 2 voices. A more practical use case is that Allegro won't let you attach a mixer to another mixer unless the formats match, whereas voices have automatic conversion. For this reason the Mixer objects in my JS-based minisphere game engine encapsulate both a mixer and a voice. Since the JS code could create a mixer of any format, attaching it to the default mixer is likely to fail. It's easier just to create multiple voices at that point and let the OS handle mixing them all together.
|
SiegeLord
Member #7,827
October 2006
|
Alright, should be implemented now. Bruce Pascoe said: Is that what's causing the crash, then? If there were two voices, then that 'silence' variable would be destroyed twice. I'm not sure about the early return business, but I think that's probably normal. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Elias
Member #358
May 2000
|
Bruce Pascoe said: A more practical use case is that Allegro won't let you attach a mixer to another mixer unless the formats match Probably wouldn't be hard to lift that restriction. The problem with voices is that there is no guarantee you will get more than one, so technically a game relying on it is faulty. -- |
Bruce Pascoe
Member #15,931
April 2015
|
The fact remains that you still can't create an 8-bit mixer, so my example use case would be impossible then.
|
|