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