diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2011-04-24 08:02:21 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2011-04-24 08:02:21 +0000 |
commit | 03f2bd594285c4077619f9039748ac7389cffaef (patch) | |
tree | 051f5ae03938fcd6dc87cf08b0bfdbb8d4214281 /gdb/gdbserver/remote-utils.c | |
parent | 3b488de17a147e0a1c7e93d68c6024353a00db72 (diff) | |
download | binutils-03f2bd594285c4077619f9039748ac7389cffaef.zip binutils-03f2bd594285c4077619f9039748ac7389cffaef.tar.gz binutils-03f2bd594285c4077619f9039748ac7389cffaef.tar.bz2 |
gdb/
* NEWS: Document the new gdbserver --once option.
gdb/doc/
* gdb.texinfo (Starting and Stopping Trace Experiments): New anchor
for disconnected tracing.
(Multi-Process Mode for @code{gdbserver}): Mention --multi and
extended-remote relationship. Mention --once.
(TCP port allocation lifecycle of @code{gdbserver}): New.
gdb/gdbserver/
* remote-utils.c (handle_accept_event): Close LISTEN_DESC only if
RUN_ONCE. Comment for the LISTEN_DESC delete_file_handler call.
(remote_prepare): New function with most of the TCP code from ...
(remote_open): ... here. Detect PORT here unconditionally. Move also
setting transport_is_reliable.
* server.c (run_once): New variable.
(gdbserver_usage): Document it.
(main): Set run_once for `--once'. Call remote_prepare. Exit after
the first run if RUN_ONCE.
* server.h (run_once, remote_prepare): New declarations.
gdb/testsuite/
* gdb.base/solib-disc.exp: Set gdbserver_reconnect_p.
* lib/gdb.exp (gdb_init): Clear gdbserver_reconnect_p.
* lib/gdbserver-support.exp (gdbserver_start): Add `--once' if
!gdbserver_reconnect_p..
(gdbserver_reconnect): Call error if !gdbserver_reconnect_p..
Diffstat (limited to 'gdb/gdbserver/remote-utils.c')
-rw-r--r-- | gdb/gdbserver/remote-utils.c | 127 |
1 files changed, 73 insertions, 54 deletions
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 650ddf8..da9018d 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -170,14 +170,21 @@ handle_accept_event (int err, gdb_client_data client_data) (char *) &tmp, sizeof (tmp)); #ifndef USE_WIN32API - close (listen_desc); /* No longer need this */ - signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply exits when the remote side dies. */ +#endif + + if (run_once) + { +#ifndef USE_WIN32API + close (listen_desc); /* No longer need this */ #else - closesocket (listen_desc); /* No longer need this */ + closesocket (listen_desc); /* No longer need this */ #endif + } + /* Even if !RUN_ONCE no longer notice new connections. Still keep the + descriptor open for add_file_handler to wait for a new connection. */ delete_file_handler (listen_desc); /* Convert IP address to string. */ @@ -200,6 +207,62 @@ handle_accept_event (int err, gdb_client_data client_data) return 0; } +/* Prepare for a later connection to a remote debugger. + NAME is the filename used for communication. */ + +void +remote_prepare (char *name) +{ + char *port_str; +#ifdef USE_WIN32API + static int winsock_initialized; +#endif + int port; + struct sockaddr_in sockaddr; + socklen_t tmp; + char *port_end; + + port_str = strchr (name, ':'); + if (port_str == NULL) + { + transport_is_reliable = 0; + return; + } + + port = strtoul (port_str + 1, &port_end, 10); + if (port_str[1] == '\0' || *port_end != '\0') + fatal ("Bad port argument: %s", name); + +#ifdef USE_WIN32API + if (!winsock_initialized) + { + WSADATA wsad; + + WSAStartup (MAKEWORD (1, 0), &wsad); + winsock_initialized = 1; + } +#endif + + listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listen_desc == -1) + perror_with_name ("Can't open socket"); + + /* Allow rapid reuse of this port. */ + tmp = 1; + setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, + sizeof (tmp)); + + sockaddr.sin_family = PF_INET; + sockaddr.sin_port = htons (port); + sockaddr.sin_addr.s_addr = INADDR_ANY; + + if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) + || listen (listen_desc, 1)) + perror_with_name ("Can't bind address"); + + transport_is_reliable = 1; +} + /* Open a connection to a remote debugger. NAME is the filename used for communication. */ @@ -274,8 +337,6 @@ remote_open (char *name) fprintf (stderr, "Remote debugging using %s\n", name); - transport_is_reliable = 0; - enable_async_notification (remote_desc); /* Register the event loop handler. */ @@ -284,64 +345,22 @@ remote_open (char *name) } else { -#ifdef USE_WIN32API - static int winsock_initialized; -#endif int port; + socklen_t len; struct sockaddr_in sockaddr; - socklen_t tmp; - char *port_end; - port = strtoul (port_str + 1, &port_end, 10); - if (port_str[1] == '\0' || *port_end != '\0') - fatal ("Bad port argument: %s", name); - -#ifdef USE_WIN32API - if (!winsock_initialized) - { - WSADATA wsad; - - WSAStartup (MAKEWORD (1, 0), &wsad); - winsock_initialized = 1; - } -#endif - - listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (listen_desc == -1) - perror_with_name ("Can't open socket"); - - /* Allow rapid reuse of this port. */ - tmp = 1; - setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, - sizeof (tmp)); - - sockaddr.sin_family = PF_INET; - sockaddr.sin_port = htons (port); - sockaddr.sin_addr.s_addr = INADDR_ANY; - - if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) - || listen (listen_desc, 1)) - perror_with_name ("Can't bind address"); - - /* If port is zero, a random port will be selected, and the - fprintf below needs to know what port was selected. */ - if (port == 0) - { - socklen_t len = sizeof (sockaddr); - if (getsockname (listen_desc, - (struct sockaddr *) &sockaddr, &len) < 0 - || len < sizeof (sockaddr)) - perror_with_name ("Can't determine port"); - port = ntohs (sockaddr.sin_port); - } + len = sizeof (sockaddr); + if (getsockname (listen_desc, + (struct sockaddr *) &sockaddr, &len) < 0 + || len < sizeof (sockaddr)) + perror_with_name ("Can't determine port"); + port = ntohs (sockaddr.sin_port); fprintf (stderr, "Listening on port %d\n", port); fflush (stderr); /* Register the event loop handler. */ add_file_handler (listen_desc, handle_accept_event, NULL); - - transport_is_reliable = 1; } } |