This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies]
- From: Pedro Alves <palves at redhat dot com>
- To: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- Cc: gdb-patches at sourceware dot org, Hui Zhu <hui_zhu at mentor dot com>
- Date: Tue, 09 Apr 2013 16:23:03 +0100
- Subject: Re: [testsuite patch] race: server-kill.exp: Connection reset by peer [Re: [patch+7.6] Fix 7.5 regression crashing GDB if gdbserver dies]
- References: <20130315195359 dot GA19841 at host2 dot jankratochvil dot net> <514C50EF dot 6030202 at redhat dot com> <20130322191841 dot GA29259 at host2 dot jankratochvil dot net> <20130406192632 dot GA8832 at host2 dot jankratochvil dot net>
On 04/06/2013 08:26 PM, Jan Kratochvil wrote:
> On Fri, 22 Mar 2013 20:18:41 +0100, Jan Kratochvil wrote:
>> +set server_pid [exp_pid -i [board_info target fileid]]
>> +remote_exec target "kill -9 $server_pid"
>> +
>> +gdb_test "step" "Remote connection closed"
>
> Getting occasionally randomly:
> Remote communication error. Target disconnected.: Connection reset by peer.
> (gdb) FAIL: gdb.server/server-kill.exp: tstatus
>
> (it was FAILing on "step" before, "tstatus" vs. "step" does not matter)
>
> I even Googled one may get ECONNRESET by writing into a closed TCP socket:
> http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket
>
> But I was unable to reproduce it myself (kernel-3.8.4-202.fc18.x86_64) with
> the attached testcase:
> sleeping ... done
> write ok
> ssize=0
> read ok
> send: send.c:53: main: Unexpected error: Broken pipe.
> Aborted
> by:
> * nc -l 5000
> * ./send (starts sleeping)
> * kill -9 `pidof ncat` (Fedora nc is ncat)
> * # send resumes sleeping
>
> I get at most EPIPE but never ECONNRESET. send vs. write and recv vs. read
> also make no difference there.
>From that url:
"Triggered when there's outstanding outgoing data that has not yet been written to the other side."
ncat is recv'ing the data you send it, so the window that
could trigger is quite small.
I've attached a standalone (no ncat) reproducer that triggers it all
the time for me.
$ ./send
sleeping ... closing ... done
send: send.c:72: main: Unexpected error: Connection reset by peer.
Aborted
> With no answer I will check in this patch as this issue seems unrelated to the
> problem, GDB still works properly even with ECONNRESET. I was just curious.
Looks fine to me.
--
Pedro Alves
#define _GNU_SOURCE 1
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#define PORT 5000
int
main (void)
{
struct sockaddr_in sockaddr;
socklen_t tmp;
int listen_fd, send_fd, recv_fd;
char charbuf;
ssize_t ssize;
int i;
setbuf (stdout, NULL);
/* bind/listen. */
errno = 0;
listen_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
assert (listen_fd != -1);
sockaddr.sin_family = PF_INET;
sockaddr.sin_port = htons (PORT);
sockaddr.sin_addr.s_addr = INADDR_ANY;
if (bind (listen_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
|| listen (listen_fd, 1))
perror ("Can't bind address");
/* Connect. */
send_fd = socket (PF_INET,SOCK_STREAM, 0);
assert (send_fd != -1);
memset (&sockaddr, 0, sizeof sockaddr);
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
sockaddr.sin_port = htons (PORT);
i = connect (send_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
assert (i == 0);
/* Accept. */
tmp = sizeof (sockaddr);
recv_fd = accept (listen_fd, (struct sockaddr *) &sockaddr, &tmp);
assert (recv_fd != -1);
/* Send. */
charbuf = 'a';
ssize = send (send_fd, &charbuf, 1, 0);
assert (ssize == 1);
/* Now that data has been queued, close the receiving end. */
fputs ("sleeping ...", stdout);
sleep (1);
fputs (" closing ...", stdout);
close (recv_fd);
sleep (1);
puts (" done");
/* Try sending again. */
charbuf = 'b';
errno = 0;
ssize = send (send_fd, &charbuf, 1, 0);
assert_perror (errno);
assert (ssize == 1);
puts ("send ok");
return 0;
}