/ Forside / Teknologi / Operativsystemer / Linux / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Linux
#NavnPoint
o.v.n. 11177
peque 7911
dk 4814
e.c 2359
Uranus 1334
emesen 1334
stone47 1307
linuxrules 1214
Octon 1100
10  BjarneD 875
Er der nogen der ved om libc bug'en med so~
Fra : Stig Johansen


Dato : 24-05-08 15:20

Hej alle.

Ok, kind of talking to myself here, men forsøger alligevel.

I forbindelse med mit lille projekt har jeg observeret, at der er en bug i
libc, hvor der tilsyneladende opstår situationer, hvor der ikke bliver
'ryddet op', og en gang imellem efterlader sockets i close_wait state.

Jeg har Googlet lidt, og der er tilsyneladende masser af tilfælde, men jeg
synes ikke der er et endegyldigt statement, der siger: 'Fixed'.

Jeg risikerer muligvis at få at vide at jeg bruger sockets forkert, og bare
skal bruge Java, så for en god ordens skyld vil jeg henvise til Sun:
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6215050>

Hvor det ser ud som om man, også i Java verdenen, efter flere år stadig
slåsser med 'problemet'.

Men som sagt, er buggen fixed, og i givet fald, i hvilken version?

--
Med venlig hilsen
Stig Johansen

 
 
Kent Friis (24-05-2008)
Kommentar
Fra : Kent Friis


Dato : 24-05-08 20:53

Den Sat, 24 May 2008 16:20:19 +0200 skrev Stig Johansen:
> Hej alle.
>
> Ok, kind of talking to myself here, men forsøger alligevel.
>
> I forbindelse med mit lille projekt har jeg observeret, at der er en bug i
> libc, hvor der tilsyneladende opstår situationer, hvor der ikke bliver
> 'ryddet op', og en gang imellem efterlader sockets i close_wait state.

En bug i libc? Sockets er noget kernen håndterer, libc burde ikke
indeholde andet end en simpel wrapper.

Hvordan lukker du din socket?

> Jeg har Googlet lidt, og der er tilsyneladende masser af tilfælde, men jeg
> synes ikke der er et endegyldigt statement, der siger: 'Fixed'.
>
> Jeg risikerer muligvis at få at vide at jeg bruger sockets forkert, og bare
> skal bruge Java, så for en god ordens skyld vil jeg henvise til Sun:
> <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6215050>

Der står ikke noget der der skulle antyde at det er en bug i libc.
Tværtimod synes jeg det ligner en bug i JVM. Bl.a. står der at
problemet opstår på både Solaris og Linux,

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (24-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 24-05-08 21:32

Kent Friis wrote:

> En bug i libc? Sockets er noget kernen håndterer, libc burde ikke
> indeholde andet end en simpel wrapper.

Ok så er det måske en bug i kernen.
Men kig på Google med søgeordene "linux libc CLOSE_WAIT bug"
Der får jeg 3660 results.
Og på den anden side hvis jeg bruger "linux kernel CLOSE_WAIT bug"
får jeg 12.800 results.
Så det er måske en bug i kernen?

> Hvordan lukker du din socket?
Jeg skulle nok have fortsat i den tidligere tråd men jeg skrev:
> Under windows anbefaler man følgende sekvens når man lukker en socket:
> (pseudo kode)
> shutdown
> repeat
>    recv
> until 0 eller error
> CloseSocket

Der sker det, at recv, tilsyneladende sporadisk, går i selvsving.
Ved den sidste observersation havde jeg en SPID 18802, hvor PID'en startede
ved 3594, altså efter minimum 15000+ request's.
Det er noget der kører hele tiden, så afhængig af hvornår SPID'en wrapper
rundt, kan der også være tale om mange flere - altså hvis den wrapper ved
32767, så 1 ud af 15.000, 1 ud af 100.000 eller ?

> Der står ikke noget der der skulle antyde at det er en bug i libc.
> Tværtimod synes jeg det ligner en bug i JVM. Bl.a. står der at
> problemet opstår på både Solaris og Linux,

Det var bare et eksempel ud af de mange 1000 resultater jfr. ovenstående.

--
Med venlig hilsen
Stig Johansen

Kent Friis (24-05-2008)
Kommentar
Fra : Kent Friis


Dato : 24-05-08 23:40

Den Sat, 24 May 2008 22:32:20 +0200 skrev Stig Johansen:
> Kent Friis wrote:
>
>> En bug i libc? Sockets er noget kernen håndterer, libc burde ikke
>> indeholde andet end en simpel wrapper.
>
> Ok så er det måske en bug i kernen.
> Men kig på Google med søgeordene "linux libc CLOSE_WAIT bug"
> Der får jeg 3660 results.
> Og på den anden side hvis jeg bruger "linux kernel CLOSE_WAIT bug"
> får jeg 12.800 results.
> Så det er måske en bug i kernen?

Eller måske ikke. Det er meget få hits for en google søgning.

>> Hvordan lukker du din socket?
> Jeg skulle nok have fortsat i den tidligere tråd men jeg skrev:
>> Under windows anbefaler man følgende sekvens når man lukker en socket:
>> (pseudo kode)
>> shutdown
>> repeat
>>    recv
>> until 0 eller error
>> CloseSocket

Windows problemer henvises til dk.edb.system.ms-windows.

> Der sker det, at recv, tilsyneladende sporadisk, går i selvsving.

Lyder som en programmør-fejl, ikke en system-fejl.

>> Der står ikke noget der der skulle antyde at det er en bug i libc.
>> Tværtimod synes jeg det ligner en bug i JVM. Bl.a. står der at
>> problemet opstår på både Solaris og Linux,
>
> Det var bare et eksempel ud af de mange 1000 resultater jfr. ovenstående.

Indtil videre har jeg set:

- nogle google hits
- noget Windows pseudo-kode
- og en side om Java-problemer

Ikke noget der antyder at der skulle være en bug i hverken kernen
eller libc.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (25-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 25-05-08 15:59

Kent Friis wrote:

>>> Hvordan lukker du din socket?
>> Jeg skulle nok have fortsat i den tidligere tråd men jeg skrev:
>>> Under windows anbefaler man følgende sekvens når man lukker en socket:
>>> (pseudo kode)
>>> shutdown
>>> repeat
>>> recv
>>> until 0 eller error
>>> CloseSocket
>
> Windows problemer henvises til dk.edb.system.ms-windows.

Det var sådan set svaret på dit spørgsmål om hvordan jeg lukker sockets,
både under windows og Linux. Windows versionen virker fint, og har gjort
det i mange mange år.
Før NPTL var Windows i virkeligheden hurtigere end Linux, så Linux har ikke
været interessant (for mig) før nu.

>> Der sker det, at recv, tilsyneladende sporadisk, går i selvsving.
>
> Lyder som en programmør-fejl, ikke en system-fejl.

Netop, og da recv ligger i libc antager jeg det er en programmør-fejl i
libc.

Hvis recv returnerer > 0 i det uendelige på en socket i close_wait state er
det helt klart en bug.

--
Med venlig hilsen
Stig Johansen

Kent Friis (25-05-2008)
Kommentar
Fra : Kent Friis


Dato : 25-05-08 16:38

Den Sun, 25 May 2008 16:59:16 +0200 skrev Stig Johansen:
> Kent Friis wrote:
>
>>>> Hvordan lukker du din socket?
>>> Jeg skulle nok have fortsat i den tidligere tråd men jeg skrev:
>>>> Under windows anbefaler man følgende sekvens når man lukker en socket:
>>>> (pseudo kode)
>>>> shutdown
>>>> repeat
>>>> recv
>>>> until 0 eller error
>>>> CloseSocket
>>
>> Windows problemer henvises til dk.edb.system.ms-windows.
>
> Det var sådan set svaret på dit spørgsmål om hvordan jeg lukker sockets,
> både under windows og Linux. Windows versionen virker fint, og har gjort
> det i mange mange år.

CloseSocket er ikke et Linux-systemkald, så hvis det virkelig er
det du gør på begge platforme, kan jeg godt forstå det ikke virker.

Eller er det end Delphi-ting? I så fald kunne det jo også være en
Delphi-bug.

Men jeg kan se at Søren er ved at grave ned i kombinationen select()+
close(), der var beskrevet på et af de links du sendte. Hvis du ikke
selv har kigget på den mulighed, så er det sikkert det der spøger.

> Før NPTL var Windows i virkeligheden hurtigere end Linux, så Linux har ikke
> været interessant (for mig) før nu.
>
>>> Der sker det, at recv, tilsyneladende sporadisk, går i selvsving.
>>
>> Lyder som en programmør-fejl, ikke en system-fejl.
>
> Netop, og da recv ligger i libc antager jeg det er en programmør-fejl i
> libc.

Nope, recv er et systemkald. Hvis det var defekt, ville der være meget
mere en et par tusinde google-hits.

> Hvis recv returnerer > 0 i det uendelige på en socket i close_wait state er
> det helt klart en bug.

"These calls return the number of bytes received, or -1 if
an error occurred."

Hvis recv returnerer > 0, bør du vel starte med at kigge på hvilke
data det er du modtager. Så er det nok nemmere at finde ud af hvor
de evt. kommer fra.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (25-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 25-05-08 18:45

Kent Friis wrote:

> CloseSocket er ikke et Linux-systemkald, så hvis det virkelig er
> det du gør på begge platforme, kan jeg godt forstå det ikke virker.

Delphi/Kylix tager udgangpunkt i navnene på windows api, og indeholder de
rigtige navne langt nede i kildeteksterne.
Netop for at undgå forvirring mellem de forskellige (i sourcekoden)
forskellige navne, skrev jeg "(pseudo kode)"

> Eller er det end Delphi-ting? I så fald kunne det jo også være en
> Delphi-bug.

Det kan det sagtens være, og det kan også være en bug i mit program.
Jeg har dog traced det ned til et loop mellem mit program og libc.

> Nope, recv er et systemkald.

Muligvis, men på mit system ligger den altså i /lib/libc-2.7.so

> Hvis det var defekt, ville der være meget
> mere en et par tusinde google-hits.

Der er noget der kunne tyde på det er select, der spøger jfr. svar til mig
selv under Sørens indlæg.

> "These calls return the number of bytes received, or -1 if
> an error occurred."

Ja, og 0 ved connection close (på windows i hvertfald)

> Hvis recv returnerer > 0, bør du vel starte med at kigge på hvilke
> data det er du modtager. Så er det nok nemmere at finde ud af hvor
> de evt. kommer fra.

Der er ikke tale om at bruge data.
Disse recv er nødvendige på Windows for at flushe bufferen.

--
Med venlig hilsen
Stig Johansen

Kent Friis (25-05-2008)
Kommentar
Fra : Kent Friis


Dato : 25-05-08 20:12

Den Sun, 25 May 2008 19:44:50 +0200 skrev Stig Johansen:
> Kent Friis wrote:
>
>> CloseSocket er ikke et Linux-systemkald, så hvis det virkelig er
>> det du gør på begge platforme, kan jeg godt forstå det ikke virker.
>
> Delphi/Kylix tager udgangpunkt i navnene på windows api, og indeholder de
> rigtige navne langt nede i kildeteksterne.
> Netop for at undgå forvirring mellem de forskellige (i sourcekoden)
> forskellige navne, skrev jeg "(pseudo kode)"

Det hjalp bare ikke på at finde ud af hvordan du lukker den.

>> Eller er det end Delphi-ting? I så fald kunne det jo også være en
>> Delphi-bug.
>
> Det kan det sagtens være, og det kan også være en bug i mit program.
> Jeg har dog traced det ned til et loop mellem mit program og libc.
>
>> Nope, recv er et systemkald.
>
> Muligvis, men på mit system ligger den altså i /lib/libc-2.7.so

Kun en wrapper, det er stadig systemkaldet der laver arbejdet.

>> Hvis det var defekt, ville der være meget
>> mere en et par tusinde google-hits.
>
> Der er noget der kunne tyde på det er select, der spøger jfr. svar til mig
> selv under Sørens indlæg.

Ja, det begynder at ligne det problem du selv linkede til. Lukker
du socket'en fra en thread imens en anden select'er på den?

Og dog, for nedenfor snakker du jo om recv.

>> "These calls return the number of bytes received, or -1 if
>> an error occurred."
>
> Ja, og 0 ved connection close (på windows i hvertfald)

Og ved non-blocking reads. Præcis som read(2) også gør.

>> Hvis recv returnerer > 0, bør du vel starte med at kigge på hvilke
>> data det er du modtager. Så er det nok nemmere at finde ud af hvor
>> de evt. kommer fra.
>
> Der er ikke tale om at bruge data.
> Disse recv er nødvendige på Windows for at flushe bufferen.

Uanset, hvis recv returnerer > 0 betyder det at den har modtaget
data. Hvilke data det er og hvor de kommer fra kan du måske se
ved at kigge på hvad det er den modtager.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (25-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 25-05-08 20:58

Kent Friis wrote:

>> Delphi/Kylix tager udgangpunkt i navnene på windows api, og indeholder de
>> rigtige navne langt nede i kildeteksterne.
>> Netop for at undgå forvirring mellem de forskellige (i sourcekoden)
>> forskellige navne, skrev jeg "(pseudo kode)"
>
> Det hjalp bare ikke på at finde ud af hvordan du lukker den.

Så får du kildekoden, men jeg havde så pillet det MS specifikke ud, da det
ikke er MS relevant.
Som nævnt er det required under MS at sørge for selv at flushe buffere.

PROCEDURE CloseSocket ( Socket : THandle );
VAR
q : ARRAY[1..255] OF CHAR ;
ql : INTEGER ;
BEGIN
{$IFDEF MSWINDOWS}
shutdown(Socket, SD_BOTH);
{$ENDIF}
{$IFDEF LINUX}
shutdown(Socket, SHUT_RDWR);
{$ENDIF}
REPEAT
ql := recv(Socket,q,SizeOf(q),0);
UNTIL ql <= 0 ;
{$IFDEF MSWINDOWS}
CloseSocket(Socket);
{$ENDIF}
{$IFDEF LINUX}
__Close(Socket);
{$ENDIF}
END;


>> Muligvis, men på mit system ligger den altså i /lib/libc-2.7.so
>
> Kun en wrapper, det er stadig systemkaldet der laver arbejdet.

Ordkløveri.

>
> Ja, det begynder at ligne det problem du selv linkede til. Lukker
> du socket'en fra en thread imens en anden select'er på den?

Der er tale om 2 processer, hvor der er en 1-1 relation mellem tråde og
sockets. Så en tråd i den ene process kan sagtens lukke mens en tråd i den
anden selecter.

Det er 2 uafhængige processer, der ikke nødvendigvis befinder sig på samme
server.

> Og dog, for nedenfor snakker du jo om recv.

Det er fordi det var det eneste sted (troede jeg indtil Søren kom med et
guldkorn) der kunne opstå et infinite loop.

> Uanset, hvis recv returnerer > 0 betyder det at den har modtaget
> data. Hvilke data det er og hvor de kommer fra kan du måske se
> ved at kigge på hvad det er den modtager.

Der er stadig tale om at flushe buffere, ikke data der skal bruges.
Principielt burde der aldrig være data, men hvis der skulle være som følge
af en close i den anden ende, så går det galt under windows.

Men som sagt, ser det ud til at det er select'en, der er en bug i.
Jeg har nogle konstruktioner med (pseudokode)
while select .... > 0
recv....

hvor tanken, og formålet, med select netop er at checke for 'readyness'
inden recv.

Og fordi jeg absolut stolede på select... er der sikker nogle steder hvor
jeg bliver nødt til at lave nogle ekstra if'er.

Det svarer lidt til at udvide:
if ready
do something...

til:
if ready
if reallyready
do something....

tsk..

--
Med venlig hilsen
Stig Johansen

Soren (News) (25-05-2008)
Kommentar
Fra : Soren (News)


Dato : 25-05-08 10:02

Stig Johansen <wopr.dk@gmaill.com> writes:

[snip]
> Jeg risikerer muligvis at få at vide at jeg bruger sockets forkert, og bare
> skal bruge Java, så for en god ordens skyld vil jeg henvise til Sun:
> <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6215050>

Den bug du linker til ser ud til at være noget med at en Selector ikke
lukker forbindelsen inden den "vågner op" (jeg kan dog ikke lige se om de
mener pga. en fejl i deres wrapper klasse).

Bruger du selectors, select( ... ), i din kode?


Mvh,
Soren

Stig Johansen (25-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 25-05-08 15:53

Soren (News wrote:

> Stig Johansen <wopr.dk@gmaill.com> writes:
>
> [snip]
>> Jeg risikerer muligvis at få at vide at jeg bruger sockets forkert, og
>> bare skal bruge Java, så for en god ordens skyld vil jeg henvise til Sun:
>> <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6215050>
>
> Den bug du linker til ser ud til at være noget med at en Selector ikke
> lukker forbindelsen inden den "vågner op" (jeg kan dog ikke lige se om de
> mener pga. en fejl i deres wrapper klasse).

Se - det var en interessant oplysning/observation.

> Bruger du selectors, select( ... ), i din kode?

Ja, det gør jeg på den initielle læsning med en passende timeout.

I og med der er tale om close_wait, havde jeg fokuseret på afslutningen af
en request, og ikke på starten af en request.

Jeg har lige testet at afbryde forbindelsen hvor jeg ved den kører i et
select loop. Det virker selvfølgelig fint når man laver enkeltstående
tests, men jeg prøver at søge/Google efter select og close_wait.

For at gøre det rigtig 'sjovt' er der i virkeligheden tale om samspil mellem
3 samtidige sockets.

Jeg har en tunnel imellem, så reelt er der tale om:
request --> tunnel --> server, hvilket giver
request --> serversocket --> clientsocket --> serversocket.

Principielt bliver alle 3 sockets lukket 'samtidig', men der kan være tale
om et eller andet timing problem.

Det skal også nævnes, at jeg med vilje tester på en gammel PII 200MHz med
100 vis af samtidige tråde, netop for at 'komme ud i hjørnerne'.

Det er ikke sikker det nogensinde vil ske på nyere udstyr.

--
Med venlig hilsen
Stig Johansen

Stig Johansen (25-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 25-05-08 18:32

Stig Johansen wrote:

> Se - det var en interessant oplysning/observation.
>
>> Bruger du selectors, select( ... ), i din kode?
>
> Ja, det gør jeg på den initielle læsning med en passende timeout.

Tog lige et kig på Google og select, jeg faldt over denne her:
<http://linux.die.net/man/2/select>

Og bemærker især under Bugs:
.........
Under Linux, select() may report a socket file descriptor as "ready for
reading", while nevertheless a subsequent read blocks. This could for
example happen when data has arrived but upon examination has wrong
checksum and is discarded. There may be other circumstances in which a file
descriptor is spuriously reported as ready.
.........

Jeg løber tilsyneladende ind i 'other circumstances' og 'spuriously'.

--
Med venlig hilsen
Stig Johansen

Stig Johansen (26-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 26-05-08 06:22

Stig Johansen wrote:

>> Bruger du selectors, select( ... ), i din kode?
>
> Ja, det gør jeg på den initielle læsning med en passende timeout.
>
> I og med der er tale om close_wait, havde jeg fokuseret på afslutningen af
> en request, og ikke på starten af en request.

Mht. starten af request, så dukkede de her 2 op på konsollen mens jeg sad og
kiggede på noget testudskrift:
Req= GET /a1b2c3d4e5f6g7h8i9/nonexistentfile.php HTTP/1.0
Req= GET /adxmlrpc.php HTTP/1.0

Der er tale om requests ude fra det store stygge i*net, og disse 2 har ikke
nogesomhelst headere med i requesten, så det er ikke umuligt, at det en den
slages, der laver en prematur close, og forvirrer select'en.

Disclaimer: Jeg kører ingen logning, og kan ikke udtale mig om hyppigheden
af den slags bot-besøg.

--
Med venlig hilsen
Stig Johansen

Michael Rasmussen (25-05-2008)
Kommentar
Fra : Michael Rasmussen


Dato : 25-05-08 16:07



Søg
Reklame
Statistik
Spørgsmål : 177459
Tips : 31964
Nyheder : 719565
Indlæg : 6408188
Brugere : 218881

Månedens bedste
Årets bedste
Sidste års bedste