problem albo cvs albo u mnie
Jakub Bogusz
qboosh w pld-linux.org
Sob, 26 Lut 2005, 21:04:51 CET
On Sat, Feb 26, 2005 at 12:07:03AM +0100, Jakub Bogusz wrote:
> On Wed, Feb 23, 2005 at 12:02:03AM +0100, Jakub Bogusz wrote:
> > On Sat, Feb 19, 2005 at 11:06:28PM +0100, Jakub Bogusz wrote:
> > > On Wed, Feb 16, 2005 at 12:55:46AM +0100, Witold Krecicki wrote:
> > > > Przy okazji - nie wiem czy to amd64-specific, ale procesy pservera
> > > > zwisaja na czyms z lockowaniem zwiazanym chyba (strace pokazuje wiszenie na
> > > > futex_costam). Nie wszystkie commity to powoduja, ale znacząca część.
> > >
> > > Nie musi być commit, wystarcza checkout.
> > >
> > > Serwer zwisa na free() w czasie obsługi sygnału podczas write().
> [...]
> > Dwie rzeczy:
> >
> > 1. czy w ogóle można używać free() w obsłudze sygnału?
Nie ma znaczenia, czy jest to obsługa sygnału.
> > Swoją drogą stos wyglądał jakby glibcowe write() też coś chciało od
> > alokacji pamięci...
A dokładniej odwrotnie - free() chciało znowu pisać.
[...]
> Update: najwyraźniej problem dotyczy tylko libc w wersji dla nptl.
Bo tylko ta wersja używa futex() w libc.
W wersji linuxthreads nie ma prawdziwych blokad jeśli nie jest używane
libpthread.
Jakby się kto chciał pobawić - w załączniku testcase.
Działa na x86 i x86_64, prawdopodobnie wszędzie (gdzie jest NPTL).
> (na kilkadziesiąt prób; w przypadku nptl średnio co drugi (albo
> i częściej) checkout przerwany ^C kończył się zostawieniem pary
> zablokowanych procesów)
E tam co drugi. 1/1 przy SIGPIPE.
> Czyli na razie mamy workaround.
Już niepotrzebny, cvs-nserver poprawiony.
--
Jakub Bogusz http://cyber.cs.net.pl/~qboosh/
-------------- następna część ---------
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main()
{
/* initialize old_tz, so tzset_internal()
* called from __tzset()
* called from strftime_l()
* called from vsyslog()
* called from __libc_message()
* called from malloc_printerr()
* will try to free it */
time_t t;
time(&t);
localtime(&t);
/* give up controlling terminal, so __libc_message() will use vsyslog() */
if(fork())
exit(0);
close(0);
close(1);
close(2);
setsid();
/* force malloc_printerr() call (from _int_free() called from free()) */
void *x = malloc(48);
free(x);
free(x);
return 0;
}
Więcej informacji o liście dyskusyjnej pld-devel-pl