So I finally managed to reproduce the wicked bug #112921 that was thought to be caused by ffmpeg. Instead, the reason why ffmpeg built with aac enabled caused xine to crash was quite different.
To find the cause of the problem there are two things that I have to give thanks to. The first is the work done trying to make sandbox working on Gentoo/FreeBSD, and for that Martin (az) who helped me understanding how loading, preloading and binding works on a normal system; the second is the explanation of -Bdirect working by Michael Meeks, and his patches for direct binding.
So, what’s the matter? For some reason xine’s plugins aren’t being built resolving all the symbols at build time, but leave some of them to being resolved at runtime, bound by the dynamic linker (ld.so). When building xine-lib with external ffmpeg (that’s what I suggest in Gentoo, as you might make use of improvements like the one for h264 that’s on latest snapshot (that finally works for me!) ), libfaad.so is loaded and the symbols from the internal copy of it in xine-lib (that’s a different version) gets overloaded by the one from the libfaad.so library. When using -Bdirect, instead, the direct binding breaks the interpose that would be otherwise in act, ending up with the plugin using its symbols as it should have been. Basically -Bdirect made xine-lib to work correctly although it was doomed to fail. Neat, eh? π
So, what can I do to fix this situation? The best thing I can think of is to hide the symbols to the loader, so that they are used internally and only internally, and to do that I can use the visibility attribute of GCC 3. This is not the same as using -fvisibility* useflags, as I don’t set the default visibility, but rather I decide, symbol by symbol, which ones should be hidden to the loading program. In this case, I want all the symbols from faad to be removed from the loader’s handling.
I’ve prepared the patch, lost about an hour on it to do, 42KB worth of patch touching almost all the headers in there. Was quite boring to prepare it, also was enough error prone for not be doable with a simple script. It was matter of an inclusion and a set of INTERNAL macros at the end of the code, but .. :/
Now it’s time to build-testing and then run-testing, I hope this will work.
The good side of this is that with this patch, by dropping the symbols that are not needed to be exported, it should also take less time to load (less bindings to do) and the file should also be a bit smaller. Interesting when you can improve performance by fixing a bug.
Although I would have be waaay more happy if I wasn’t doing this on one of the (probably) last free days I have and to fix a problem I didn’t have for a while π
Self-sacrifice, masochism, or I’m just an idiot? π
what about dropping faad from xine and let it use it from ffmpeg?lu – simpler solution leads to simpler failure?
Well, the faad shipped with xine-lib is a completely different version that seemed to be needed for some reasons in the past, so I’m not keen on changing that.I’m working on an improved patch tho, so just wait and I’ll try to provide all the needed information π
A close option that should even work in all cases is symbol versioning. With the -default-symver linker option a default version (the soname) is added to the resulting binaries/libraries. And ld.so is smart enough to know that it should resolve foo@libfaad.so.1 to libfaad.so.1 and foo@libfaad.so.xine to xine internal (the intuition this last thing suggests is wrong, but the stuff does work).