aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2011-04-24 08:02:21 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2011-04-24 08:02:21 +0000
commit03f2bd594285c4077619f9039748ac7389cffaef (patch)
tree051f5ae03938fcd6dc87cf08b0bfdbb8d4214281 /gdb/gdbserver
parent3b488de17a147e0a1c7e93d68c6024353a00db72 (diff)
downloadfsf-binutils-gdb-03f2bd594285c4077619f9039748ac7389cffaef.zip
fsf-binutils-gdb-03f2bd594285c4077619f9039748ac7389cffaef.tar.gz
fsf-binutils-gdb-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')
-rw-r--r--gdb/gdbserver/ChangeLog13
-rw-r--r--gdb/gdbserver/remote-utils.c127
-rw-r--r--gdb/gdbserver/server.c13
-rw-r--r--gdb/gdbserver/server.h2
4 files changed, 99 insertions, 56 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index ff1311d..5d6dd4a 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,16 @@
+2011-04-24 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * 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.
+
2011-04-19 Tom Tromey <tromey@redhat.com>
* win32-low.c (handle_load_dll): Remove duplicate "the".
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;
}
}
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 2f4484f..8b9133b 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -40,6 +40,9 @@ static int extended_protocol;
static int response_needed;
static int exit_requested;
+/* --once: Exit after the first connection has closed. */
+int run_once;
+
int multi_process;
int non_stop;
@@ -2312,7 +2315,9 @@ gdbserver_usage (FILE *stream)
" --debug Enable general debugging output.\n"
" --remote-debug Enable remote protocol debugging output.\n"
" --version Display version information and exit.\n"
- " --wrapper WRAPPER -- Run WRAPPER to start new programs.\n");
+ " --wrapper WRAPPER -- Run WRAPPER to start new programs.\n"
+ " --once Exit after the first connection has "
+ "closed.\n");
if (REPORT_BUGS_TO[0] && stream == stdout)
fprintf (stream, "Report bugs to \"%s\".\n", REPORT_BUGS_TO);
}
@@ -2536,6 +2541,8 @@ main (int argc, char *argv[])
}
}
}
+ else if (strcmp (*next_arg, "--once") == 0)
+ run_once = 1;
else
{
fprintf (stderr, "Unknown argument: %s\n", *next_arg);
@@ -2648,6 +2655,8 @@ main (int argc, char *argv[])
exit (1);
}
+ remote_prepare (port);
+
while (1)
{
noack_mode = 0;
@@ -2676,7 +2685,7 @@ main (int argc, char *argv[])
getpkt to fail; close the connection and reopen it at the
top of the loop. */
- if (exit_requested)
+ if (exit_requested || run_once)
{
detach_or_kill_for_exit ();
exit (0);
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 77f5dd6..f1147d6 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -355,6 +355,7 @@ extern int disable_packet_Tthread;
extern int disable_packet_qC;
extern int disable_packet_qfThreadInfo;
+extern int run_once;
extern int multi_process;
extern int non_stop;
@@ -406,6 +407,7 @@ int putpkt (char *buf);
int putpkt_binary (char *buf, int len);
int putpkt_notif (char *buf);
int getpkt (char *buf);
+void remote_prepare (char *name);
void remote_open (char *name);
void remote_close (void);
void write_ok (char *buf);