> -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Kevin Day > Sent: den 15 maj 2008 17:54 > To: uClibc > Subject: ldso libdl dl_cleanup issue - Possible Fix > > > I distantly remember swinging at everything in sight trying to find > and resolve this problem. > This happened on a number of projects and is shown by valgrind, but > I've historically got from uClibc that it was "X Project"'s problem > and when I went to "X Project" they said it was uClibc's problem. > > So, I was recently looking at the same problem again, this time with > abiword as the "X project". > I got the usual: > ==2807== Invalid read of size 4 > ==2807== at 0x4600D8C: dl_cleanup (in /lib/libdl-0.9.28.so) > ==2807== by 0x4000ADC: (within /lib/ld-uClibc-0.9.28.so) > ==2807== by 0x4B4E021: exit (in /lib/libuClibc-0.9.28.so) > ==2807== by 0x4B2C46D: __uClibc_main (in /lib/libuClibc-0.9.28.so) > ==2807== by 0x8171D1F: _start (in /bin/abiword) > ==2807== Address 0x5a0f96c is 4 bytes inside a block of size > 24 free'd > ==2807== at 0x401933C: free (in > /toolchain/lib/valgrind/x86-linux/vgpreload_memcheck.so) > ==2807== by 0x4600C8A: (within /lib/libdl-0.9.28.so) > ==2807== by 0x4600D8B: dl_cleanup (in /lib/libdl-0.9.28.so) > ==2807== by 0x4000ADC: (within /lib/ld-uClibc-0.9.28.so) > ==2807== by 0x4B4E021: exit (in /lib/libuClibc-0.9.28.so) > ==2807== by 0x4B2C46D: __uClibc_main (in /lib/libuClibc-0.9.28.so) > ==2807== by 0x8171D1F: _start (in /bin/abiword) > > again, dl_cleanup seems to be reading unallocated memory > according to valgrind. > After recompiling uClibc with debug symbols, I noticed that it was > caused by two lines in: uClibc-0.9.28.3/ldso/libdl/libdl.c > Line 136: do_dlclose(d, 1); > and in depth, Line 578: free(handle); > > Considering that handle was being used during this entire process it > should be allocated.. > > I decided to look at the logic of the dl_cleanup function and the > do_dlclose function. > > Here is a simple explanation of the problem I see: > > dl_cleanup will call do_dlclose with the pointer "d" > Inside of do_dlclose, "d" will ultimately get free'd > After do_dlclose finishes executing, the for loop from dl_cleanup will > then take the pointer "d" and move it to the next pointer. > And this is where I am confused, if "d" was free'd by the do_dlclose > function, then how can it use the "d" pointer to iterate along the > next location? > So it makes sense that d(NULL)->(Next Pointer) generates an invalid > read according to valgrind. > > To test this, I changed the contents of dl_cleanup to: > { > struct dyn_elf *d = _dl_handles; > struct dyn_elf *n; > > if (d){ > n = d->next; > do_dlclose(d, 1); > > while (n){ > d = n; > n = d->next; > do_dlclose(d, 1); > } > } > } > > I then installed libdl.so, and re-ran valgrind on abiword and the > invalid read no longer appeared. > > Does this sound right or is there some loophole in my logic or some > aspect of do_dlclose(..) I am missing? > > -- > Kevin Day
>From a quick look at the code in ldso/libdl/libdl.c I would say that your assessment is correct. Here is a cleaner solution (this is based on dl_cleanup() from SVN, not the 0.9.28.3 version): void dl_cleanup(void) { struct dyn_elf *d; struct dyn_elf *n; for (d = _dl_handles; d; d = n) { n = d->next_handle; do_dlclose(d, 1); } } //Peter _______________________________________________ uClibc mailing list uClibc@uclibc.org http://busybox.net/cgi-bin/mailman/listinfo/uclibc