Heads-Up: Beware of xmlCleanupParser() when your package links against libxml2

Lennart Poettering mzerqung at 0pointer.de
Wed Jan 13 21:39:43 UTC 2010


On Wed, 13.01.10 16:07, Tom Lane (tgl at redhat.com) wrote:

> 
> Lennart Poettering <mzerqung at 0pointer.de> writes:
> > There's something else that came to my mind: if libxml2 is loaded into
> > memory indirectly because some dlopen'ed module wanted it, and then
> > used, and then unloaded again because the module got dlcose'd again,
> > won't you leak TLS vars unless the xmlCleanupParser() function was
> > called properly before? In that case, not calling xmlCleanupParser()
> > is an error, right? And calling it, too, since some other
> > plugin/thread might still need it. Which means you are in a dilemma:
> > in either case you are doing it wrong.
> 
> Got it in one.  libxml's API in this area is unusably broken, and needs
> a ground-up redesign not random messages telling users that they didn't
> use it right --- there *is* no right way to use it.

Dunno. I wouldn't be so harsh. If libxml2 is linked with -z nodelete
(maybe it already is? I never checked...) this dilemma *does* go
away. And if then xmlCleanupParser() would be renamed to something
like xmlCallMeOnlyIfYouValgrindMeOtherWiseYouSuck() and then make the
symbol xmlCleanupParser() a NOP plus a gcc linker warning things are
more than fixed in my eyes.

(Oh, and the issue above would leak memory too, not just TLS, but TLS
is usually more of a scarce resource)

Oh, and let's note that other libraries have exactly the same
probs. Let's pick dbus for example which many might consider a
benchmark in many ways. There is dbus_shutdown() which does about the
same thing as xmlCleanupParser(). And libdbus isn't linked with -z
nodelete. A module that pulls it in has hence exactly the same
problems. For example, let's say there was a module by the name of
/lib64/security/pam_ck_connector.so which links against libdbus.so it
will leak memory each time it is invoked by a process that not by
itself links against libdbus, which we'll call "/bin/login" for
now. And there you have it: the same dilemma: either the module calls
dbus_shutdown and hence breaks every other dbus-using PAM module that
might be loaded, or it might not call it in which case it will leak
memory. Same dilemma.

It's a common problem. In fact, libpulse had a similar issue until i
added -z nodelete to its linker line.

Lennart

-- 
Lennart Poettering                        Red Hat, Inc.
lennart [at] poettering [dot] net
http://0pointer.net/lennart/           GnuPG 0x1A015CC4


More information about the devel mailing list