I encountered an invalid memory write bug in FMOD Ex versions 4.08.07 (but had it with the previous two release versions as well) when I close an internet stream.
It took me a while to pinpoint the problem since running "netstream" from the examples only crashes when running under valgrind (because the memory address is freed but obviously the page is still mapped). So for a while I thought it might be my setup.
Output from valgrind is (main.c from examples/netstream):
[quote:37ov4zto]==16511== Process terminating with default action of signal 11 (SIGSEGV)
==16511== Access not within mapped region at address 0x1000001A7
==16511== at 0x4E98A64: FMOD::File::close() (in /home/carjay/sources/fmodapi40807linux64/api/lib/libfmodex64.so.4.08.07)
==16511== by 0x4E89A72: FMOD::Codec::release() (in /home/carjay/sources/fmodapi40807linux64/api/lib/libfmodex64.so.4.08.07)
==16511== by 0x4EA87AE: FMOD::SoundI::release(bool) (in /home/carjay/sources/fmodapi40807linux64/api/lib/libfmodex64.so.4.08.07)
==16511== by 0x4EA43BD: FMOD::Sound::release() (in /home/carjay/sources/fmodapi40807linux64/api/lib/libfmodex64.so.4.08.07)
==16511== by 0x401C08: main (main.c:166)[/quote:37ov4zto]
Since this is probably not really useful for debugging I looked at the disassembly output to help you a bit.
FMOD::File::close() internally calls FMOD::FileThread::release(). Right after returning, a value of 0 is written into a structure or object. This is the write which fails (for the address is no longer valid, it seems to be part of a structure which is freed internally by FMOD::FileThread::release()).
But it should be fairly easy to reproduce with valgrind.
If it means anything, I’m using the C-version of the API and running under Kubuntu Feisty with OSS as the output sound system.
Oh, and as can be seen from the valgrind output it is an AMD64-system
If you need more information, please ask.
- Carjay asked 11 years ago
I actually found this error a little while back now when upgrading the MacOSX code to use POSIX style threads and critical sections as I used the existing Linux code as a reference.
For some reason though the fix was never put into the Linux release, I will do this fix now, so your problems should be resolved in our next release.
Thanks for your debugging.
Thanks for replying.
I forgot to mention that I was using a Shoutcast stream. Maybe it’s depending on the codec used.
There is not much to do, I can choose any of the streams on shoutcast.com and it will show this segmentation fault every time right after pressing ESC.
I did not modify the example, just typed make. I did not test it under 32 bit Linux so cannot say if it happens there.
The gcc used was "(GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)".
Will try to test it on another system to see if it occurs there as well.
Sorry, was away on a business trip for over a week.
I tested it with 32 and 64 bit Linux now. Result is that 32 bit works (only produces some "Conditional jump or move depends on uninitialised value(s)" in pthread_mutex_destroy, but I guess these are harmless and really within the pthreads-library).
Then I tested it on an otherwise pretty much untouched 64bit Suse Linux Enterprise Desktop-System. As said above I just compiled the netstream example with make and ran it with valgrind. The same segmentation fault as reported in my first message occurs.
This was tested with one of the shoutcast streams from the Winamp website.
There really is nothing special about it except for running it under valgrind.
Ok, I finally found something that might explain the strange behaviour.
Could you please check the implementation of "FMOD_OS_CriticalSection_Free(FMOD_OS_CRITICALSECTION*)" in your Linux sources? It seems like the call to pthread_mutex_destroy(pthread_mutex_t *mutex) in there receives a pointer to the stack where the pointer to the pthread_mutex_t is stored instead of the pointer to pthread_mutex_t itself.
If my observation from gdb is correct, this leads to the stack becoming corrupted on return. This does not always happen because sometimes the pthread_mutex_destroy-code returns EBUSY (due to random values on the stack) which is not caught but nothing is deinitialized in this case and the stack is left intact.
For testing this theory, I created a small test wrapper that simply replaces pthread_mutex_destroy and calls it with the correct pointer. All crashes have disappeared so I would kindly ask you to have a look at the source code to see if my assumption is correct.
Please login first to submit.