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..
This commit is contained in:
parent
3b488de17a
commit
03f2bd5942
12 changed files with 186 additions and 60 deletions
|
@ -1,3 +1,8 @@
|
|||
2011-04-24 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* NEWS: Document the new gdbserver --once option.
|
||||
|
||||
2011-04-21 Jie Zhang <jzhang918@gmail.com>
|
||||
|
||||
* MAINTAINERS: Update my email address.
|
||||
|
|
4
gdb/NEWS
4
gdb/NEWS
|
@ -3,6 +3,10 @@
|
|||
|
||||
*** Changes since GDB 7.3
|
||||
|
||||
* The new option --once causes GDBserver to stop listening for connections once
|
||||
the first connection is made. The listening port used by GDBserver will
|
||||
become available after that.
|
||||
|
||||
*** Changes in GDB 7.3
|
||||
|
||||
* GDB has a new command: "thread find [REGEXP]".
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2011-04-24 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* 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.
|
||||
|
||||
2011-04-23 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* gdb.texinfo (Server): Improve indexing. Index all optional
|
||||
|
|
|
@ -10435,6 +10435,7 @@ Enter actions for tracepoint #1, one per line.
|
|||
(@value{GDBP}) @b{tstop}
|
||||
@end smallexample
|
||||
|
||||
@anchor{disconnected tracing}
|
||||
@cindex disconnected tracing
|
||||
You can choose to continue running the trace experiment even if
|
||||
@value{GDBN} disconnects from the target, voluntarily or
|
||||
|
@ -16232,9 +16233,42 @@ or process ID to attach, use the @option{--multi} command line option.
|
|||
Then you can connect using @kbd{target extended-remote} and start
|
||||
the program you want to debug.
|
||||
|
||||
@code{gdbserver} does not automatically exit in multi-process mode.
|
||||
You can terminate it by using @code{monitor exit}
|
||||
(@pxref{Monitor Commands for gdbserver}).
|
||||
In multi-process mode @code{gdbserver} does not automatically exit unless you
|
||||
use the option @option{--once}. You can terminate it by using
|
||||
@code{monitor exit} (@pxref{Monitor Commands for gdbserver}). Note that the
|
||||
conditions under which @code{gdbserver} terminates depend on how @value{GDBN}
|
||||
connects to it (@kbd{target remote} or @kbd{target extended-remote}). The
|
||||
@option{--multi} option to @code{gdbserver} has no influence on that.
|
||||
|
||||
@subsubsection TCP port allocation lifecycle of @code{gdbserver}
|
||||
|
||||
This section applies only when @code{gdbserver} is run to listen on a TCP port.
|
||||
|
||||
@code{gdbserver} normally terminates after all of its debugged processes have
|
||||
terminated in @kbd{target remote} mode. On the other hand, for @kbd{target
|
||||
extended-remote}, @code{gdbserver} stays running even with no processes left.
|
||||
@value{GDBN} normally terminates the spawned debugged process on its exit,
|
||||
which normally also terminates @code{gdbserver} in the @kbd{target remote}
|
||||
mode. Therefore, when the connection drops unexpectedly, and @value{GDBN}
|
||||
cannot ask @code{gdbserver} to kill its debugged processes, @code{gdbserver}
|
||||
stays running even in the @kbd{target remote} mode.
|
||||
|
||||
When @code{gdbserver} stays running, @value{GDBN} can connect to it again later.
|
||||
Such reconnecting is useful for features like @ref{disconnected tracing}. For
|
||||
completeness, at most one @value{GDBN} can be connected at a time.
|
||||
|
||||
@cindex @option{--once}, @code{gdbserver} option
|
||||
By default, @code{gdbserver} keeps the listening TCP port open, so that
|
||||
additional connections are possible. However, if you start @code{gdbserver}
|
||||
with the @option{--once} option, it will stop listening for any further
|
||||
connection attempts after connecting to the first @value{GDBN} session. This
|
||||
means no further connections to @code{gdbserver} will be possible after the
|
||||
first one. It also means @code{gdbserver} will terminate after the first
|
||||
connection with remote @value{GDBN} has closed, even for unexpectedly closed
|
||||
connections and even in the @kbd{target extended-remote} mode. The
|
||||
@option{--once} option allows reusing the same port number for connecting to
|
||||
multiple instances of @code{gdbserver} running on the same host, since each
|
||||
instance closes its port after the first connection.
|
||||
|
||||
@subsubsection Other Command-Line Arguments for @code{gdbserver}
|
||||
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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. */
|
||||
#else
|
||||
closesocket (listen_desc); /* No longer need this */
|
||||
#endif
|
||||
|
||||
if (run_once)
|
||||
{
|
||||
#ifndef USE_WIN32API
|
||||
close (listen_desc); /* No longer need this */
|
||||
#else
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2011-04-24 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* 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..
|
||||
|
||||
2011-04-20 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.cp/cpcompletion.exp (complete class methods)
|
||||
|
|
|
@ -19,6 +19,7 @@ if {[skip_shlib_tests]} {
|
|||
return 0
|
||||
}
|
||||
|
||||
set gdbserver_reconnect_p 1
|
||||
if { [info proc gdb_reconnect] == "" } {
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -2809,6 +2809,11 @@ proc gdb_init { args } {
|
|||
# especially having color output turned on can cause tests to fail.
|
||||
setenv GREP_OPTIONS ""
|
||||
|
||||
# Clear $gdbserver_reconnect_p.
|
||||
global gdbserver_reconnect_p
|
||||
set gdbserver_reconnect_p 1
|
||||
unset gdbserver_reconnect_p
|
||||
|
||||
return [eval default_gdb_init $args];
|
||||
}
|
||||
|
||||
|
|
|
@ -218,10 +218,21 @@ proc gdbserver_start { options arguments } {
|
|||
|
||||
# Fire off the debug agent.
|
||||
set gdbserver_command "$gdbserver"
|
||||
|
||||
# If gdbserver_reconnect will be called $gdbserver_reconnect_p must be
|
||||
# set to true already during gdbserver_start.
|
||||
global gdbserver_reconnect_p
|
||||
if {![info exists gdbserver_reconnect_p] || !$gdbserver_reconnect_p} {
|
||||
# GDB client could accidentally connect to a stale server.
|
||||
append gdbserver_command " --once"
|
||||
}
|
||||
|
||||
if { $options != "" } {
|
||||
append gdbserver_command " $options"
|
||||
}
|
||||
|
||||
append gdbserver_command " :$portnum"
|
||||
|
||||
if { $arguments != "" } {
|
||||
append gdbserver_command " $arguments"
|
||||
}
|
||||
|
@ -315,6 +326,12 @@ proc gdbserver_reconnect { } {
|
|||
global gdbserver_protocol
|
||||
global gdbserver_gdbport
|
||||
|
||||
global gdbserver_reconnect_p;
|
||||
if {![info exists gdbserver_reconnect_p] || !$gdbserver_reconnect_p} {
|
||||
error "gdbserver_reconnect_p is not set before gdbserver_reconnect"
|
||||
return 0
|
||||
}
|
||||
|
||||
return [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport]
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue