You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 2792 Reporter: administrator Status: closed Resolution: fixed Priority: normal Severity: minor Category: ~DO NOT USE (was: OCaml general)
Bug description
Hi,
I have written a small example that demonstrates the earlier mentioned bug
in "flush" that leads to sudden death after a "Connection reset by peer":
file: client.ml
open Unix
open Pervasives
let _ =
sleep 1; (* Guarantee that the server is ready for action )
let s = socket PF_INET SOCK_STREAM 0 in
let sockaddr = ADDR_INET (inet_addr_any, 9876) in
connect s sockaddr;
let ic = in_channel_of_descr s in
let oc = out_channel_of_descr s in
sleep 1; ( Guarantee that the server process has terminated )
(try
( Try to read from dead server process. The server will respond
with an RST segment, which triggers an ECONNRESET-error. )
print_endline (input_line ic); flush stdout;
with exc ->
print_endline ("caught exception: " ^ Printexc.to_string exc);
flush stdout);
print_endline "before output"; flush stdout;
output_string oc "x"; ( Put dummy data into buffer )
flush oc; ( XXX: Flush buffer: we crash here )
print_endline "after output"; flush stdout ( Should not be reached *)
file: server.ml
open Unix
let _ =
let s = socket PF_INET SOCK_STREAM 0 in
setsockopt s SO_REUSEADDR true;
let sockaddr = ADDR_INET (inet_addr_any, 9876) in
bind s sockaddr;
listen s 1;
(* Wait for connection, but do not accept *)
select [s] [] [] 1000.0
Just compile the two examples, start the server, then the client.
It may take more than one invocation.
I have written a small example that demonstrates the earlier mentioned bug
in "flush" that leads to sudden death after a "Connection reset by peer":
Thanks for the repro case. On my machine, I see the client dying on a
"Broken pipe" (SIGPIPE) signal, which I believe is the normal behavior
for a write on a closed or unconnected socket. This is not
symmetrical with a read on such a socket, which generates a Unix error
code, but that's the Unix API... So, nothing unusual here.
The "Out_of_memory" comes from ocamldebug, not from the programs.
It's a simple bug in ocamldebug (= instead of == to compare mutable
cyclic structures). I'll fix that.
Thanks for the repro case. On my machine, I see the client dying on a
"Broken pipe" (SIGPIPE) signal, which I believe is the normal behavior
for a write on a closed or unconnected socket. This is not
symmetrical with a read on such a socket, which generates a Unix error
code, but that's the Unix API... So, nothing unusual here.
Ah, ok, I see. This asymmetry in the Unix-API is indeed not very
intuitiv so I didn't expect that I'd have to catch signals here.
Thanks for the info!
Original bug ID: 2792
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)
Bug description
Hi,
I have written a small example that demonstrates the earlier mentioned bug
in "flush" that leads to sudden death after a "Connection reset by peer":
file: client.ml
open Unix
open Pervasives
let _ =
sleep 1; (* Guarantee that the server is ready for action )
let s = socket PF_INET SOCK_STREAM 0 in
let sockaddr = ADDR_INET (inet_addr_any, 9876) in
connect s sockaddr;
let ic = in_channel_of_descr s in
let oc = out_channel_of_descr s in
sleep 1; ( Guarantee that the server process has terminated )
(try
( Try to read from dead server process. The server will respond
with an RST segment, which triggers an ECONNRESET-error. )
print_endline (input_line ic); flush stdout;
with exc ->
print_endline ("caught exception: " ^ Printexc.to_string exc);
flush stdout);
print_endline "before output"; flush stdout;
output_string oc "x"; ( Put dummy data into buffer )
flush oc; ( XXX: Flush buffer: we crash here )
print_endline "after output"; flush stdout ( Should not be reached *)
file: server.ml
open Unix
let _ =
let s = socket PF_INET SOCK_STREAM 0 in
setsockopt s SO_REUSEADDR true;
let sockaddr = ADDR_INET (inet_addr_any, 9876) in
bind s sockaddr;
listen s 1;
(* Wait for connection, but do not accept *)
select [s] [] [] 1000.0
Just compile the two examples, start the server, then the client.
It may take more than one invocation.
Best regards,
Markus
--
Markus Mottl http://www.oefai.at/~markus markus@oefai.at
The text was updated successfully, but these errors were encountered: