|
From: Ludovic D. <ld...@li...> - 2005-06-09 14:37:58
|
Hi ! I'm currently trying to debug atftp, a multicast, multithreaded tftp server. http://packages.debian.org/testing/net/atftp I sometimes get a segfault in tftpd.c:736 in the 'free(data)'. So I ran it under Valgrind (Debian v2.4.0-2) and here's what I get: data: 1badda48 <--- debug info: a printf("%x", data); before the free(data) ==6998== Invalid write of size 4 ==6998== at 0x1B936C55: pthread_create@@GLIBC_2.1 (in /lib/libpthread-0.10.so ==6998== by 0x804A2C9: main (tftpd.c:469) ==6998== Address 0x1BADDA48 is 0 bytes inside a block of size 112 free'd ==6998== at 0x1B904B04: free (vg_replace_malloc.c:152) ==6998== by 0x804A682: tftpd_receive_request (tftpd.c:736) ==6998== by 0x1B934E50: pthread_start_thread (in /lib/libpthread-0.10.so) ==6998== by 0x1BA69929: clone (in /lib/libc-2.3.2.so) So it seems to say that pthread_create tried to use a freed block and that this block has been freed at tftpd.c:736 ? If that's what valgrind wants to say, then I do not understand anything ! Indeed for each incoming tftp request: 1- the thread specific 'data' block is calloced at tftpd.c:410 2- then passed to pthread_create() at tftpd.c:469 3- and finally freed by the thread at tftpd.c:736, before a pthread_exit(). Only one thing is sure: if I remove the free(data), no more segfaults... Maybe the stack is corrupt so that valgrind displays strange info ? -- Ludovic DROLEZ |
|
From: Paul P. <ppl...@gm...> - 2005-06-09 18:49:00
|
On 6/9/05, Ludovic Drolez <ld...@li...> wrote: >=20 > So it seems to say that pthread_create tried to use a freed block and tha= t this > block has been freed at tftpd.c:736 ? Yes. The bug is as follows: new =3D calloc(1, sizeof(thread_data)); ... pthread_create(&new->tid, ..., new);=20 At this point it is indeterminate which thread goes first -- the "current" one or the "new" one. If the "new" thread runs to *completion* (including the free(data) on line 736) *before* the "current" thread had a chance to write new->tid, then you'll have the bug which VG cought for you: writing to now dangling memory. Cheers, |
|
From: Ludovic D. <lud...@li...> - 2005-06-10 08:39:06
|
Paul Pluzhnikov wrote: > On 6/9/05, Ludovic Drolez <ld...@li...> wrote: > >>So it seems to say that pthread_create tried to use a freed block and that this >>block has been freed at tftpd.c:736 ? > > > Yes. The bug is as follows: > > new = calloc(1, sizeof(thread_data)); ... > pthread_create(&new->tid, ..., new); > > At this point it is indeterminate which thread goes first -- the > "current" one or the "new" one. If the "new" thread runs to > *completion* (including the free(data) on line 736) *before* the > "current" thread had a chance to write new->tid, then you'll have > the bug which VG cought for you: writing to now dangling memory. > Yes but, new->tid is malloc'd for each new thread, it's not shared. So for example, the "new" thread cannot free the memory calloc'd for the "current" thread... Cheers, -- Ludovic DROLEZ |
|
From: Dennis L. <pla...@in...> - 2005-06-10 09:09:12
|
Am Freitag, den 10.06.2005, 10:38 +0200 schrieb Ludovic Drolez: > Paul Pluzhnikov wrote: > > On 6/9/05, Ludovic Drolez <ld...@li...> wrote: > > > >>So it seems to say that pthread_create tried to use a freed block and that this > >>block has been freed at tftpd.c:736 ? > > > > > > Yes. The bug is as follows: > > > > new = calloc(1, sizeof(thread_data)); ... > > pthread_create(&new->tid, ..., new); > > > > At this point it is indeterminate which thread goes first -- the > > "current" one or the "new" one. If the "new" thread runs to > > *completion* (including the free(data) on line 736) *before* the > > "current" thread had a chance to write new->tid, then you'll have > > the bug which VG cought for you: writing to now dangling memory. > > > > Yes but, new->tid is malloc'd for each new thread, it's not shared. > So for example, the "new" thread cannot free the memory calloc'd for the > "current" thread... > It is shared, since pthread_create writes the new->tid field in the *current* thread, not in the spawned one (where it might be freed() before the *current* thread comes to run again) > Cheers, |
|
From: Ludovic D. <ld...@li...> - 2005-06-10 10:09:18
|
Dennis Lubert wrote: > Am Freitag, den 10.06.2005, 10:38 +0200 schrieb Ludovic Drolez: > >>Paul Pluzhnikov wrote: >> >>>On 6/9/05, Ludovic Drolez <ld...@li...> wrote: >>> >>> >>>>So it seems to say that pthread_create tried to use a freed block and that this >>>>block has been freed at tftpd.c:736 ? >>> >>> >>>Yes. The bug is as follows: >>> >>> new = calloc(1, sizeof(thread_data)); ... >>> pthread_create(&new->tid, ..., new); >>> >>>At this point it is indeterminate which thread goes first -- the >>>"current" one or the "new" one. If the "new" thread runs to >>>*completion* (including the free(data) on line 736) *before* the >>>"current" thread had a chance to write new->tid, then you'll have >>>the bug which VG cought for you: writing to now dangling memory. >>> >> >>Yes but, new->tid is malloc'd for each new thread, it's not shared. >>So for example, the "new" thread cannot free the memory calloc'd for the >>"current" thread... >> > > It is shared, since pthread_create writes the new->tid field in the > *current* thread, not in the spawned one (where it might be freed() > before the *current* thread comes to run again) Ok, now I understand. I thought that the 1st thing that pthread_create() did, was to assign a value to new->tid. But you say that it might work like this: pthread_create(...): clone() in my thread : free(new) new->tid = segfault So, we should never allocate memory for new->tid to fix this bug. Many thanks for your valuable explanations ! Cheers, -- Ludovic DROLEZ Linbox / Free&ALter Soft www.linbox.com www.linbox.org tel: +33 3 87 50 87 90 152 rue de Grigy - Technopole Metz 2000 57070 METZ |