Saturday, January 31, 2009

Package dependencies

Let's start with this fact: linphone uses the ffmpeg library to encode video. How can various package managers be informed about this fact by maintainers while building the linphone package?

In Arch Linux, the dependency information is expressed in the PKGBUILD file in a very straightforward way:

depends=('alsa-lib' 'ffmpeg>=20080715' 'gtk2' 'libexosip2>=3.1.0' 'speex>=1.1.12')


And this propagates in the same form into the binary package of linphone. But, is it really what is needed to prevent installation of a broken package? No.

The linphone binary from the package uses the libavcodec.so.51 library, not just "any ffmpeg >=20080715". So the linphone package will break when the ffmpeg package starts providing libavcodec.so.52 (and this already happened in the testing repository). Let's see how other package managers deal with the situation.

RPM-based distributions have to add this line to the linphone.spec script:

BuildRequires:  ffmpeg-dev


Then, RPM will build the linphone package and examine the resulting binaries. It will notice that the linphone binary uses the libavcodec.so.51 library and will add the dependency on that library (not on some abstract "ffmpeg" package). This way, if the new ffmpeg package no longer includes libavcodec.so.51, RPM will notice that the linphone package now has an unsatisfied dependency, print an error message and refuse to upgrade ffmpeg.

This is better than the Arch Linux way, but requires some external tool to know that libavcodec.so.51 is actually in the ffmpeg package. Otherwise, how would the "install linphone with all dependencies" request be handled?

Now let's talk about Debian and its derivatives. They also have a notion of a build-time dependency, and it is expressed in the debian/control file:

Build-Depends: ..., libavcodec-dev, ...


When the package is built, debhelper also notices that the resulting linphone binary depends on libavcodec.so.51, and searches the installed packages for this library. As a result, the dependency on the found package is added automatically to the binary package of linphone. This looks similar to the Arch Linux case, but Debian has a policy that requires the shared library version to be mentioned in the package name. I.e., linphone gets a dependency on "libavcodec51" package, while "libavcodec52" is a completely different package that (assuming no bugs) can be installed in parallel with libavcodec51, thus allowing the rebuilds of other packages for the ffmpeg upgrade to take place gradually, without any hurry and without the broken intermediate state.

Tuesday, January 6, 2009

Inefficient use of Valgrind

This is already stated in the documentation, but let me repeat. Valgrind can detect memory leaks only if the application uses malloc() and free(), or, in C++, operator new() and operator delete().

This is not always the case. E.g., ImageMagick, when configured with the --enable-embeddable switch, uses mmap() directly in order to allocate memory for its needs. Other problematic cases involve custom memory pools on top of malloc() and free(), as done in Glib.

So, if you want to find a memory leak with Valgrind, the first thing to do is to turn off all those custom memory allocation schemes. OTOH, if the buggy thing is the allocator itself, this will hide the bug.