* [patch] [gdbserver] Fix multi-GB error log files
@ 2011-03-06 14:23 Jan Kratochvil
2011-03-15 17:48 ` Pedro Alves
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-03-06 14:23 UTC (permalink / raw)
To: gdb-patches
Hi,
currently when one runs the (parallel) testsuite there are many gigabytes of
error messages:
readchar: Got EOF
Remote side has terminated connection. GDBserver will reopen the connection.
Can't bind address: Address already in use.
Remote side has terminated connection. GDBserver will reopen the connection.
Can't bind address: Address already in use.
[... 1020x]
Remote side has terminated connection. GDBserver will reopen the connection.
Can't open socket: Too many open files.
Remote side has terminated connection. GDBserver will reopen the connection.
Can't open socket: Too many open files.
[... infinitely till some timeout occurs]
reproducible by:
window A:
./gdbserver :1234 ./gdbserver
window B:
while :;do ./gdbserver :1234 ./gdbserver; done
window C:
telnet localhost 1234
^]q
window B:
-> Listening on port 1234
window A:
-> infinite loop
while regression testing it I found these FAILs but they probably happen
randomly and one should fix gdb_assert first anyway before tuning the
testsuite:
linux-low.c:3584: A problem internal to GDBserver has been detected.
Assertion `lwp->suspended >= 0' failed.
FAIL: gdb.mi/mi-nonstop.exp: w0,i0 stop (timeout)
and
linux-low.c:3584: A problem internal to GDBserver has been detected.
Assertion `lwp->suspended >= 0' failed.
=thread-group-exited,id="i1"
&"Remote connection closed\n"
~"thread.c:81: internal-error: inferior_thread: Assertion `tp' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugging session? "
~"(y or n) "
FAIL: gdb.mi/mi-nsintrall.exp: stop 0 (timeout)
with a similar one for:
FAIL: gdb.mi/mi-nsmoribund.exp: stop 0 (timeout)
There are multiple ways how to solve this problem.
One would be to change the code from
[patch] testsuite: Fix multiple runs in parallel on a single host [Re: RFC: parallelize "make check"]
http://sourceware.org/ml/gdb-patches/2009-07/msg00008.html
commit c470d5dd46806b8e19925f58053923373b4c75d7
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
* lib/gdbserver-support.exp (gdbserver_start): Loop spawning
gdbserver increasing $portnum if "Can't bind address" has been seen.
to just choose random port number instead of trying to consecutively find
a first free port number which leads to races. Still the problem would be
less racy but still racy (*).
(*) such as gdb.base/break-interp.exp relies now on that the address space
randomization maps the executable on two consecutive runs on a different
place. Sometimes it does not.
This change introduces the listening port to remain open during the default
gdbserver run for users (when "--once" is not used). This is a change where
the user can mistakenly connect to the "dead" but still listening port.
But I find the assumption that the port will be available when the user will
want to reconnect as a worse one than the dead-but-listening port.
Then gdbserver could also keep the listening port open for each run.
There would not be needed the gdbserver option --once and also no
$gdbserver_reconnect_p would be needed. I do not mind much but I find the
whole testsuite gdbserver operation as casuing more headache with all the
listening-but-dead ports hanging around. One should use --once when (s)he is
sure no reconnect will be needed even during regular use IMO.
Also when --once is already introduced it could be made default (that is
introduce an option "--permanent" to keep the current behavior). But this
changes the behavior of gdbserver which the users may be used to.
Unfortunately it does not seem to be possible to have a port reserved (so that
no other program may bind+listen on it) while giving ECONNREFUSED. Any
BACKLOG of listen() gives on Linux kernel an effective backlog of at least 3.
No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu against default
gdbserver mode (**), except the cases described above. Any possible
USE_WIN32API issues are untested.
(**) In fact against a patched gdbserver with sleep (1) there to avoid the
multi-gigabyte log files difficult to handle for comparisons, that is
with the first patch from:
http://sourceware.org/ml/gdb-patches/2011-03/msg00330.html
I am not going to check it in without an approval.
The hook in gdb_init could be probably moved some way into
gdbserver-support.exp, if there is such a concern.
Thanks,
Jan
gdb/gdbserver/
2011-03-06 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.
gdb/testsuite/
2011-03-06 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..
--- 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;
}
}
--- 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 closed. */
+int run_once;
+
int multi_process;
int non_stop;
@@ -2312,7 +2315,8 @@ 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 closed.\n");
if (REPORT_BUGS_TO[0] && stream == stdout)
fprintf (stream, "Report bugs to \"%s\".\n", REPORT_BUGS_TO);
}
@@ -2536,6 +2540,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 +2654,8 @@ main (int argc, char *argv[])
exit (1);
}
+ remote_prepare (port);
+
while (1)
{
noack_mode = 0;
@@ -2676,7 +2684,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);
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -349,6 +349,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;
@@ -400,6 +401,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);
--- a/gdb/testsuite/gdb.base/solib-disc.exp
+++ b/gdb/testsuite/gdb.base/solib-disc.exp
@@ -19,6 +19,7 @@ if {[skip_shlib_tests]} {
return 0
}
+set gdbserver_reconnect_p 1
if { [info proc gdb_reconnect] == "" } {
return 0
}
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -2799,6 +2799,11 @@ proc gdb_init { args } {
setenv LC_ALL C
setenv LANG C
+ # Clear $gdbserver_reconnect_p.
+ global gdbserver_reconnect_p
+ set gdbserver_reconnect_p 1
+ unset gdbserver_reconnect_p
+
return [eval default_gdb_init $args];
}
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -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]
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-06 14:23 [patch] [gdbserver] Fix multi-GB error log files Jan Kratochvil
@ 2011-03-15 17:48 ` Pedro Alves
2011-03-15 18:04 ` Daniel Jacobowitz
2011-03-15 18:35 ` Jan Kratochvil
0 siblings, 2 replies; 18+ messages in thread
From: Pedro Alves @ 2011-03-15 17:48 UTC (permalink / raw)
To: gdb-patches; +Cc: Jan Kratochvil, Daniel Jacobowitz
On Sunday 06 March 2011 11:55:36, Jan Kratochvil wrote:
> This change introduces the listening port to remain open during the default
> gdbserver run for users (when "--once" is not used). This is a change where
> the user can mistakenly connect to the "dead" but still listening port.
It seems that this change stands on its own independently from
the --once stuff. I'm worried about whether this breaks use
cases. E.g., as is, you can spawn several instances of
gdbserver + connect, while only needing to open one port in
your firewall. Or perhaps IDEs are relying on that when
spawning the second (and nth) connections to the same
board (while leaving the previous sessions still running).
Daniel, do you have an opinion?
> But I find the assumption that the port will be available when the user will
> want to reconnect as a worse one than the dead-but-listening port.
I see your point. Not sure if there's a single right answer.
--
Pedro Alves
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-15 17:48 ` Pedro Alves
@ 2011-03-15 18:04 ` Daniel Jacobowitz
2011-03-15 18:35 ` Jan Kratochvil
1 sibling, 0 replies; 18+ messages in thread
From: Daniel Jacobowitz @ 2011-03-15 18:04 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil
On Tue, Mar 15, 2011 at 05:42:56PM +0000, Pedro Alves wrote:
> On Sunday 06 March 2011 11:55:36, Jan Kratochvil wrote:
> > This change introduces the listening port to remain open during the default
> > gdbserver run for users (when "--once" is not used). This is a change where
> > the user can mistakenly connect to the "dead" but still listening port.
>
> It seems that this change stands on its own independently from
> the --once stuff. I'm worried about whether this breaks use
> cases. E.g., as is, you can spawn several instances of
> gdbserver + connect, while only needing to open one port in
> your firewall. Or perhaps IDEs are relying on that when
> spawning the second (and nth) connections to the same
> board (while leaving the previous sessions still running).
>
> Daniel, do you have an opinion?
I don't have much of an opinion on this. The current behavior is
somewhat useful; if gdbserver is running, you can't connect to it.
Jan has correctly identified a potential problem if something "steals"
the port while gdbserver is still running, but nothing hits it in
practice except the testsuite.
--
Daniel Jacobowitz
Mentor Graphics
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-15 17:48 ` Pedro Alves
2011-03-15 18:04 ` Daniel Jacobowitz
@ 2011-03-15 18:35 ` Jan Kratochvil
2011-03-15 18:48 ` Pedro Alves
1 sibling, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-03-15 18:35 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz
On Tue, 15 Mar 2011 18:42:56 +0100, Pedro Alves wrote:
> I'm worried about whether this breaks use
> cases. E.g., as is, you can spawn several instances of
> gdbserver + connect, while only needing to open one port in
> your firewall. Or perhaps IDEs are relying on that when
> spawning the second (and nth) connections to the same
> board (while leaving the previous sessions still running).
In such case we can make --once default:
On Sun, 06 Mar 2011 12:55:36 +0100, Jan Kratochvil wrote:
# Also when --once is already introduced it could be made default (that is
# introduce an option "--permanent" to keep the current behavior). But this
# changes the behavior of gdbserver which the users may be used to.
It was not made the default just for backward compatibility which you state
got broken anyway.
Thanks,
Jan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-15 18:35 ` Jan Kratochvil
@ 2011-03-15 18:48 ` Pedro Alves
2011-03-15 19:28 ` Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Pedro Alves @ 2011-03-15 18:48 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches, Daniel Jacobowitz
On Tuesday 15 March 2011 18:04:23, Jan Kratochvil wrote:
> On Tue, 15 Mar 2011 18:42:56 +0100, Pedro Alves wrote:
> > I'm worried about whether this breaks use
> > cases. E.g., as is, you can spawn several instances of
> > gdbserver + connect, while only needing to open one port in
> > your firewall. Or perhaps IDEs are relying on that when
> > spawning the second (and nth) connections to the same
> > board (while leaving the previous sessions still running).
>
> In such case we can make --once default:
I don't think that's a good idea. When the user does
"disconnect" (, or gdb crashes), we don't want gdbserver to
exit.
>
> On Sun, 06 Mar 2011 12:55:36 +0100, Jan Kratochvil wrote:
> # Also when --once is already introduced it could be made default (that is
> # introduce an option "--permanent" to keep the current behavior). But this
> # changes the behavior of gdbserver which the users may be used to.
>
> It was not made the default just for backward compatibility which you state
> got broken anyway.
I'm confused. Backwards compatibility would be broken by the listen
socket change. But that socket change looked orthogonal
to the --once stuff? Won't either of the changes fix the problem?
--
Pedro Alves
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-15 18:48 ` Pedro Alves
@ 2011-03-15 19:28 ` Jan Kratochvil
2011-03-15 20:06 ` Pedro Alves
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-03-15 19:28 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz
On Tue, 15 Mar 2011 19:36:02 +0100, Pedro Alves wrote:
> I'm confused. Backwards compatibility would be broken by the listen
> socket change. But that socket change looked orthogonal
> to the --once stuff? Won't either of the changes fix the problem?
If people depend on:
> > On Tue, 15 Mar 2011 18:42:56 +0100, Pedro Alves wrote:
> > > you can spawn several instances of
> > > gdbserver + connect, while only needing to open one port in
> > > your firewall. Or perhaps IDEs are relying on that when
> > > spawning the second (and nth) connections to the same
> > > board (while leaving the previous sessions still running).
then it is already racy - at least for multiple users sharing the same target
box. But it is IMO racy even on fast enough clicking in Eclipse by a single
user.
To remove the racy case some kind of backward compatibility with current
setups has to be broken.
If you want to keep the racy behavior for users (for its other benefits) I can
propose a patch fixing only the testsuite and not affecting the normal
gdbserver executions by users in any way.
Thanks,
Jan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-15 19:28 ` Jan Kratochvil
@ 2011-03-15 20:06 ` Pedro Alves
2011-03-16 10:20 ` Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Pedro Alves @ 2011-03-15 20:06 UTC (permalink / raw)
To: gdb-patches; +Cc: Jan Kratochvil, Daniel Jacobowitz
On Tuesday 15 March 2011 19:18:24, Jan Kratochvil wrote:
> To remove the racy case some kind of backward compatibility with current
> setups has to be broken.
No doubt. As I said, I'm not sure there's a single right answer.
I think it'd be prudent to consider such a socket change early in
the release cycle, not late. If you can fix the testsuite with
just the --once change (or something else), then I am suggesting
we consider that (more pressing issue) independently of
fixing this particular race.
> If you want to keep the racy behavior for users (for its other benefits) I can
> propose a patch fixing only the testsuite and not affecting the normal
> gdbserver executions by users in any way.
Sounds like a plan.
--
Pedro Alves
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-15 20:06 ` Pedro Alves
@ 2011-03-16 10:20 ` Jan Kratochvil
2011-03-16 11:44 ` Pedro Alves
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-03-16 10:20 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz
Hi Pedro,
if the only concern is the late release cycle phase it can wait. When it
waited so many ears I do not find a need to provide a temporary testsuite-only
fix just to fix the 7.3 gdbserver testsuite.
So the question is whether do you want to fix the racey user-facing behavior
of gdbserver or not, independent of the GDB release cycle.
Thanks,
Jan
On Tue, 15 Mar 2011 20:41:16 +0100, Pedro Alves wrote:
> On Tuesday 15 March 2011 19:18:24, Jan Kratochvil wrote:
>
> > To remove the racy case some kind of backward compatibility with current
> > setups has to be broken.
>
> No doubt. As I said, I'm not sure there's a single right answer.
> I think it'd be prudent to consider such a socket change early in
> the release cycle, not late. If you can fix the testsuite with
> just the --once change (or something else), then I am suggesting
> we consider that (more pressing issue) independently of
> fixing this particular race.
>
> > If you want to keep the racy behavior for users (for its other benefits) I can
> > propose a patch fixing only the testsuite and not affecting the normal
> > gdbserver executions by users in any way.
>
> Sounds like a plan.
>
> --
> Pedro Alves
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files
2011-03-16 10:20 ` Jan Kratochvil
@ 2011-03-16 11:44 ` Pedro Alves
2011-04-17 14:05 ` [patch] [gdbserver] Fix multi-GB error log files [doc review] Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Pedro Alves @ 2011-03-16 11:44 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches, Daniel Jacobowitz
On Wednesday 16 March 2011 09:32:28, Jan Kratochvil wrote:
> Hi Pedro,
>
> if the only concern is the late release cycle phase it can wait. When it
> waited so many ears I do not find a need to provide a temporary testsuite-only
> fix just to fix the 7.3 gdbserver testsuite.
>
> So the question is whether do you want to fix the racey user-facing behavior
> of gdbserver or not, independent of the GDB release cycle.
Yes, I'm willing to give that a try. I do think your patch solves
it in a way that makes sense: without --once, the default, we leave the
socket open; with --once, we release it as soon as possible, so the user
can still open several debug sessions with the same port, if he's okay
with not being able to reconnect back to the same gdbserver.
--
Pedro Alves
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-03-16 11:44 ` Pedro Alves
@ 2011-04-17 14:05 ` Jan Kratochvil
2011-04-17 16:31 ` Eli Zaretskii
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-04-17 14:05 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Daniel Jacobowitz, Eli Zaretskii
On Wed, 16 Mar 2011 11:13:41 +0100, Pedro Alves wrote:
> Yes, I'm willing to give that a try. I do think your patch solves
> it in a way that makes sense: without --once, the default, we leave the
> socket open; with --once, we release it as soon as possible, so the user
> can still open several debug sessions with the same port, if he's okay
> with not being able to reconnect back to the same gdbserver.
Considering this as an approval after 7.3 has been branched.
I will check it in after the new gdb/doc/ part approval.
Thanks,
Jan
gdb/gdbserver/
2011-04-17 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.
gdb/doc/
2011-04-17 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (Multi-Process Mode for @code{gdbserver}): Mention --once.
(Other Command-Line Arguments for @code{gdbserver}): New paragraph for
--once.
gdb/testsuite/
2011-04-17 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..
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -16228,9 +16228,9 @@ 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}).
@subsubsection Other Command-Line Arguments for @code{gdbserver}
@@ -16240,6 +16240,13 @@ status information about the debugging process. The
remote protocol debug output. These options are intended for
@code{gdbserver} development and for bug reports to the developers.
+The @option{--once} will terminate @code{gdbserver} after the first connection
+with remote @value{GDBN} has closed. By default @code{gdbserver} keeps the
+listening TCP port open so that is is always available in the case a reconnect
+is needed. Using the @option{--once} will close the port upon the first
+connection of @value{GDBN} and such @code{gdbserver} then does not support
+reconnect from new @value{GDBN}.
+
The @option{--wrapper} option specifies a wrapper to launch programs
for debugging. The option should be followed by the name of the
wrapper, then any command-line arguments to pass to the wrapper, then
--- 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;
}
}
--- 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);
--- 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);
--- a/gdb/testsuite/gdb.base/solib-disc.exp
+++ b/gdb/testsuite/gdb.base/solib-disc.exp
@@ -19,6 +19,7 @@ if {[skip_shlib_tests]} {
return 0
}
+set gdbserver_reconnect_p 1
if { [info proc gdb_reconnect] == "" } {
return 0
}
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -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];
}
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -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]
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-17 14:05 ` [patch] [gdbserver] Fix multi-GB error log files [doc review] Jan Kratochvil
@ 2011-04-17 16:31 ` Eli Zaretskii
2011-04-22 21:42 ` Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2011-04-17 16:31 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: pedro, gdb-patches, dan
> Date: Sun, 17 Apr 2011 16:04:28 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: gdb-patches@sourceware.org, Daniel Jacobowitz <dan@codesourcery.com>,
> Eli Zaretskii <eliz@gnu.org>
>
> I will check it in after the new gdb/doc/ part approval.
Thanks.
> +The @option{--once} will terminate @code{gdbserver} after the first connection
> +with remote @value{GDBN} has closed. By default @code{gdbserver} keeps the
> +listening TCP port open so that is is always available in the case a reconnect
> +is needed. Using the @option{--once} will close the port upon the first
> +connection of @value{GDBN} and such @code{gdbserver} then does not support
> +reconnect from new @value{GDBN}.
"will close the port upon the first connection" sounds wrong to me;
did you mean "disconnection" perhaps?
Also, this text should have an index entry for this new option.
Finally, do we want to mention this in NEWS?
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-17 16:31 ` Eli Zaretskii
@ 2011-04-22 21:42 ` Jan Kratochvil
2011-04-23 6:16 ` Eli Zaretskii
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-04-22 21:42 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: pedro, gdb-patches, dan
On Sun, 17 Apr 2011 18:31:11 +0200, Eli Zaretskii wrote:
> > +The @option{--once} will terminate @code{gdbserver} after the first connection
> > +with remote @value{GDBN} has closed. By default @code{gdbserver} keeps the
> > +listening TCP port open so that is is always available in the case a reconnect
> > +is needed. Using the @option{--once} will close the port upon the first
> > +connection of @value{GDBN} and such @code{gdbserver} then does not support
> > +reconnect from new @value{GDBN}.
>
> "will close the port upon the first connection" sounds wrong to me;
> did you mean "disconnection" perhaps?
I meant really "connection". I see the gdbserver behavior wrt its termination
and now even TCP closing rules is complex, I hope it got explained now.
Pedro's facts review is sure welcome.
> Also, this text should have an index entry for this new option.
I do not see --debug, --remote-debug or --wrapper documented either so please
fix those first to have a template.
> Finally, do we want to mention this in NEWS?
Done.
Thanks,
Jan
gdb/gdbserver/
2011-04-22 Jan Kratochvil <jan.kratochvil@redhat.com>
* NEWS: Document the new gdbserver --once option.
* 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/doc/
2011-04-22 Jan Kratochvil <jan.kratochvil@redhat.com>
* 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/testsuite/
2011-04-17 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..
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
*** Changes since GDB 7.3
+* GDBserver has started to keep its listening port allocated. You can free the
+ listening port for its reusal by the new GDBserver option --once. In such
+ case GDB will no longer be able to reconnect to such GDBserver.
+
*** Changes in GDB 7.3
* GDB has a new command: "thread find [REGEXP]".
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -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
@@ -16227,11 +16228,41 @@ redirection (@pxref{Arguments}).
To start @code{gdbserver} without supplying an initial command to run
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}).
+the program you want to debug. Option @option{--multi} is not directly related
+to @kbd{target extended-remote} (therefore @kbd{target remote} is also
+compatible) and vice versa.
+
+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}).
+
+@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.
+Thefrefore when the connection drop 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.
+
+By default @code{gdbserver} keeps the listening TCP port open so that is is
+always available in the case a reconnect is needed. There exists also
+a @code{gdbserver} option @option{--once} which will free the listening TCP
+port immediately after first @value{GDBN} connects. In such case later new
+@value{GDBN} will no longer be able to reconnect to such @code{gdbserver}. 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 purpose of option
+@option{--once} is to enable reusing the same port number for connections to
+multiple @code{gdbserver}s running at the same host.
@subsubsection Other Command-Line Arguments for @code{gdbserver}
--- 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;
}
}
--- 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);
--- 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);
--- a/gdb/testsuite/gdb.base/solib-disc.exp
+++ b/gdb/testsuite/gdb.base/solib-disc.exp
@@ -19,6 +19,7 @@ if {[skip_shlib_tests]} {
return 0
}
+set gdbserver_reconnect_p 1
if { [info proc gdb_reconnect] == "" } {
return 0
}
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -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];
}
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -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]
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-22 21:42 ` Jan Kratochvil
@ 2011-04-23 6:16 ` Eli Zaretskii
2011-04-23 8:00 ` Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2011-04-23 6:16 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: pedro, gdb-patches, dan
> Date: Fri, 22 Apr 2011 23:41:45 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: pedro@codesourcery.com, gdb-patches@sourceware.org, dan@codesourcery.com
>
> > Also, this text should have an index entry for this new option.
>
> I do not see --debug, --remote-debug or --wrapper documented either so please
> fix those first to have a template.
I did that (with the patch shown below), but please note that we
already have GDB options indexed, so you have the template already.
> > Finally, do we want to mention this in NEWS?
>
> Done.
Thanks.
> *** Changes since GDB 7.3
>
> +* GDBserver has started to keep its listening port allocated. You can free the
> + listening port for its reusal by the new GDBserver option --once. In such
> + case GDB will no longer be able to reconnect to such GDBserver.
I would rephrase:
GDBserver now keeps its listening port open, unless you start
GDBserver with the --once option. Keeping the listening port open
allows subsequent reconnections from another GDB session.
> + Option @option{--multi} is not directly related
> +to @kbd{target extended-remote} (therefore @kbd{target remote} is also
> +compatible) and vice versa.
It's not clear to me how this sentence is related to the surrounding
text. What potential problem did you try to prevent by that?
In any case, please say "the @option{--multi} option", not "option
@option{--multi}".
> +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}).
> +
> +@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
^
Missing comma there.
> +extended-remote} @code{gdbserver} stays running even with no processes left.
^
And here.
> +@value{GDBN} normally terminates the spawned debugged process on its exit which
^
And there.
> +Thefrefore when the connection drop unexpectedly and @value{GDBN} cannot ask
^^^^^^^^^^
A typo. And also comma missing after "therefore" and after
"unexpectedly". Also, "drops", not "drop".
> +@code{gdbserver} to kill its debugged processes @code{gdbserver} stays running
^
Missing comma.
> +When @code{gdbserver} stays running @value{GDBN} can connect to it again later.
^
And here.
> +Such reconnecting is useful for features like @ref{disconnected tracing}. For
> +completeness at most one @value{GDBN} can be connected at a time.
^
And here.
> +By default @code{gdbserver} keeps the listening TCP port open so that is is
^ ^
And there.
> +always available in the case a reconnect is needed.
"... port open, so that additional connections are possible."
> There exists also
> +a @code{gdbserver} option @option{--once} which will free the listening TCP
> +port immediately after first @value{GDBN} connects.
"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."
> In such case later new
> +@value{GDBN} will no longer be able to reconnect to such @code{gdbserver}.
"This means no further connections to @code{gdbserver} will be
possible after the first one."
> + The purpose of option
> +@option{--once} is to enable reusing the same port number for connections to
> +multiple @code{gdbserver}s running at the same host.
"The purpose of the @option{--once} option is ..."
However, is the above the only purpose of this option? If not, saying
"the purpose" is inaccurate. How about the following rewording:
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.
Thanks.
Here's what I committed a few minutes ago:
2011-04-23 Eli Zaretskii <eliz@gnu.org>
* gdb.texinfo (Server): Improve indexing. Index all optional
switches to gdbserver.
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.823
retrieving revision 1.824
diff -u -r1.823 -r1.824
--- gdb/doc/gdb.texinfo 20 Apr 2011 18:05:26 -0000 1.823
+++ gdb/doc/gdb.texinfo 23 Apr 2011 05:47:43 -0000 1.824
@@ -16135,6 +16135,7 @@
@subsection Running @code{gdbserver}
@cindex arguments, to @code{gdbserver}
+@cindex @code{gdbserver}, command-line arguments
Run @code{gdbserver} on the target system. You need a copy of the
program you want to debug, including any libraries it requires.
@@ -16181,6 +16182,8 @@
@code{target remote} command.
@subsubsection Attaching to a Running Program
+@cindex attach to a program, @code{gdbserver}
+@cindex @option{--attach}, @code{gdbserver} option
On some targets, @code{gdbserver} can also attach to running programs.
This is accomplished via the @code{--attach} argument. The syntax is:
@@ -16193,7 +16196,6 @@
to point @code{gdbserver} at a binary for the running process.
@pindex pidof
-@cindex attach to a program by name
You can debug processes by name instead of process ID if your target has the
@code{pidof} utility:
@@ -16206,8 +16208,8 @@
@code{-s} option to only return the first process ID.
@subsubsection Multi-Process Mode for @code{gdbserver}
-@cindex gdbserver, multiple processes
-@cindex multiple processes with gdbserver
+@cindex @code{gdbserver}, multiple processes
+@cindex multiple processes with @code{gdbserver}
When you connect to @code{gdbserver} using @code{target remote},
@code{gdbserver} debugs the specified program only once. When the
@@ -16224,6 +16226,7 @@
arguments are supported, except for wildcard expansion and I/O
redirection (@pxref{Arguments}).
+@cindex @option{--multi}, @code{gdbserver} option
To start @code{gdbserver} without supplying an initial command to run
or process ID to attach, use the @option{--multi} command line option.
Then you can connect using @kbd{target extended-remote} and start
@@ -16235,12 +16238,15 @@
@subsubsection Other Command-Line Arguments for @code{gdbserver}
+@cindex @option{--debug}, @code{gdbserver} option
The @option{--debug} option tells @code{gdbserver} to display extra
-status information about the debugging process. The
-@option{--remote-debug} option tells @code{gdbserver} to display
+status information about the debugging process.
+@cindex @option{--remote-debug}, @code{gdbserver} option
+The @option{--remote-debug} option tells @code{gdbserver} to display
remote protocol debug output. These options are intended for
@code{gdbserver} development and for bug reports to the developers.
+@cindex @option{--wrapper}, @code{gdbserver} option
The @option{--wrapper} option specifies a wrapper to launch programs
for debugging. The option should be followed by the name of the
wrapper, then any command-line arguments to pass to the wrapper, then
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-23 6:16 ` Eli Zaretskii
@ 2011-04-23 8:00 ` Jan Kratochvil
2011-04-23 11:09 ` Eli Zaretskii
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-04-23 8:00 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: pedro, gdb-patches, dan
On Sat, 23 Apr 2011 08:15:38 +0200, Eli Zaretskii wrote:
> GDBserver now keeps its listening port open, unless you start
> GDBserver with the --once option. Keeping the listening port open
> allows subsequent reconnections from another GDB session.
BTW personally I read it as if GDBserver did not support reconnections before
and that reconnections are a new feature (which they are not).
> > + Option @option{--multi} is not directly related
> > +to @kbd{target extended-remote} (therefore @kbd{target remote} is also
> > +compatible) and vice versa.
>
> It's not clear to me how this sentence is related to the surrounding
> text. What potential problem did you try to prevent by that?
Yes, I was considering to post it as a separate patch but (a) it would be
a hassle for one sentence and (b) it is all related together anyway.
--multi, remote/extended-remote and --once all together affect when gdbserver
will / will not terminate. Normally AFAIK one uses either:
--multi with extended-remote
or
(default) with remote
so I was curious if one can mix the two modes. And to my surprise gdbserver
behavior in which cases it terminates depends on how GDB connects to it
(remote/extended-remote) instead of the gdbserver arguments (--multi).
This is why this question seemed to me logical in the context of explaining
all the GDB termination rules which needed to be explained together with the
port allocation rules.
> > +terminated in @kbd{target remote} mode. On the other hand for @kbd{target
> ^
> Missing comma there.
You wrote it as "On the other, hand for " but I have used "On the other hand,
for ", either a typo or a font layout problem on your side.
> > + The purpose of option
> > +@option{--once} is to enable reusing the same port number for connections to
> > +multiple @code{gdbserver}s running at the same host.
>
> "The purpose of the @option{--once} option is ..."
>
> However, is the above the only purpose of this option? If not, saying
> "the purpose" is inaccurate.
Not the only one, it is also useful if any unexpected situation happens in the
testsuite gdbserver will no longer be needlessly running.
> How about the following rewording:
Used.
> * gdb.texinfo (Server): Improve indexing. Index all optional
> switches to gdbserver.
Added @cindex for --once.
Used all your other suggestions, I am not aware much of the commas.
I will check it in if no futher comments appear.
Thanks,
Jan
gdb/gdbserver/
2011-04-23 Jan Kratochvil <jan.kratochvil@redhat.com>
* NEWS: Document the new gdbserver --once option.
* 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/doc/
2011-04-23 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.
gdb/testsuite/
2011-04-17 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..
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
*** Changes since GDB 7.3
+* GDBserver now keeps its listening port open, unless you start GDBserver with
+ the --once option. Keeping the listening port open allows subsequent
+ reconnections from another GDB session.
+
*** Changes in GDB 7.3
* GDB has a new command: "thread find [REGEXP]".
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -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
@@ -16230,11 +16231,43 @@ redirection (@pxref{Arguments}).
To start @code{gdbserver} without supplying an initial command to run
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}).
+the program you want to debug. The @option{--multi} option is not directly
+related to @kbd{target extended-remote} (therefore @kbd{target remote} is also
+compatible) and vice versa.
+
+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}).
+
+@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}
--- 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;
}
}
--- 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);
--- 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);
--- a/gdb/testsuite/gdb.base/solib-disc.exp
+++ b/gdb/testsuite/gdb.base/solib-disc.exp
@@ -19,6 +19,7 @@ if {[skip_shlib_tests]} {
return 0
}
+set gdbserver_reconnect_p 1
if { [info proc gdb_reconnect] == "" } {
return 0
}
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -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];
}
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -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]
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-23 8:00 ` Jan Kratochvil
@ 2011-04-23 11:09 ` Eli Zaretskii
2011-04-24 8:24 ` Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2011-04-23 11:09 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: pedro, gdb-patches, dan
> Date: Sat, 23 Apr 2011 10:00:23 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: pedro@codesourcery.com, gdb-patches@sourceware.org, dan@codesourcery.com
>
> On Sat, 23 Apr 2011 08:15:38 +0200, Eli Zaretskii wrote:
> > GDBserver now keeps its listening port open, unless you start
> > GDBserver with the --once option. Keeping the listening port open
> > allows subsequent reconnections from another GDB session.
>
> BTW personally I read it as if GDBserver did not support reconnections before
> and that reconnections are a new feature (which they are not).
Ah, in that case, that's my mistake: I indeed thought the possibility
to reconnect was new. So I guess the right wording of this entry
would be
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.
> > > + Option @option{--multi} is not directly related
> > > +to @kbd{target extended-remote} (therefore @kbd{target remote} is also
> > > +compatible) and vice versa.
> >
> > It's not clear to me how this sentence is related to the surrounding
> > text. What potential problem did you try to prevent by that?
>
> Yes, I was considering to post it as a separate patch but (a) it would be
> a hassle for one sentence and (b) it is all related together anyway.
>
> --multi, remote/extended-remote and --once all together affect when gdbserver
> will / will not terminate. Normally AFAIK one uses either:
> --multi with extended-remote
> or
> (default) with remote
> so I was curious if one can mix the two modes. And to my surprise gdbserver
> behavior in which cases it terminates depends on how GDB connects to it
> (remote/extended-remote) instead of the gdbserver arguments (--multi).
> This is why this question seemed to me logical in the context of explaining
> all the GDB termination rules which needed to be explained together with the
> port allocation rules.
How about this modified text, then?
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.
> > > +terminated in @kbd{target remote} mode. On the other hand for @kbd{target
> > ^
> > Missing comma there.
>
> You wrote it as "On the other, hand for " but I have used "On the other hand,
> for ", either a typo or a font layout problem on your side.
It's my mistake, sorry. The comma should be after "hand", of course.
> Added @cindex for --once.
>
> Used all your other suggestions, I am not aware much of the commas.
>
> I will check it in if no futher comments appear.
Apart of the above two issues, the new text is fine with me. Thanks.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-24 8:24 ` Jan Kratochvil
@ 2011-04-24 7:35 ` Eli Zaretskii
2011-04-24 8:04 ` [commit] " Jan Kratochvil
0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2011-04-24 7:35 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: pedro, gdb-patches, dan
> Date: Sun, 24 Apr 2011 09:08:43 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: pedro@codesourcery.com, gdb-patches@sourceware.org, dan@codesourcery.com
>
> This is the final form, I will check it in in some time.
The documentation parts are fine with me. Thanks.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [commit] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-24 7:35 ` Eli Zaretskii
@ 2011-04-24 8:04 ` Jan Kratochvil
0 siblings, 0 replies; 18+ messages in thread
From: Jan Kratochvil @ 2011-04-24 8:04 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: pedro, gdb-patches, dan
On Sun, 24 Apr 2011 09:19:28 +0200, Eli Zaretskii wrote:
> The documentation parts are fine with me. Thanks.
Checked in.
http://sourceware.org/ml/gdb-cvs/2011-04/msg00148.html
Thanks,
Jan
Changed ChangeLogs only:
--- src/gdb/ChangeLog 2011/04/22 02:45:20 1.12946
+++ src/gdb/ChangeLog 2011/04/24 08:02:15 1.12947
@@ -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.
--- src/gdb/doc/ChangeLog 2011/04/23 05:47:43 1.1176
+++ src/gdb/doc/ChangeLog 2011/04/24 08:02:18 1.1177
@@ -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
--- src/gdb/gdbserver/ChangeLog 2011/04/19 18:04:09 1.473
+++ src/gdb/gdbserver/ChangeLog 2011/04/24 08:02:20 1.474
@@ -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".
--- src/gdb/testsuite/ChangeLog 2011/04/20 19:42:51 1.2675
+++ src/gdb/testsuite/ChangeLog 2011/04/24 08:02:20 1.2676
@@ -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)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] [gdbserver] Fix multi-GB error log files [doc review]
2011-04-23 11:09 ` Eli Zaretskii
@ 2011-04-24 8:24 ` Jan Kratochvil
2011-04-24 7:35 ` Eli Zaretskii
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2011-04-24 8:24 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: pedro, gdb-patches, dan
On Sat, 23 Apr 2011 13:09:00 +0200, Eli Zaretskii wrote:
> 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.
I read this one correctly.
> How about this modified text, then?
>
> 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.
OK (+moved it to IMO a more appropriate paragraph).
> Apart of the above two issues, the new text is fine with me. Thanks.
This is the final form, I will check it in in some time.
Thanks,
Jan
gdb/gdbserver/
2011-04-24 Jan Kratochvil <jan.kratochvil@redhat.com>
* NEWS: Document the new gdbserver --once option.
* 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/doc/
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.
gdb/testsuite/
2011-04-17 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..
--- a/gdb/NEWS
+++ b/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]".
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -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}
--- 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;
}
}
--- 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);
--- 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);
--- a/gdb/testsuite/gdb.base/solib-disc.exp
+++ b/gdb/testsuite/gdb.base/solib-disc.exp
@@ -19,6 +19,7 @@ if {[skip_shlib_tests]} {
return 0
}
+set gdbserver_reconnect_p 1
if { [info proc gdb_reconnect] == "" } {
return 0
}
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -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];
}
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -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]
}
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2011-04-24 8:24 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-06 14:23 [patch] [gdbserver] Fix multi-GB error log files Jan Kratochvil
2011-03-15 17:48 ` Pedro Alves
2011-03-15 18:04 ` Daniel Jacobowitz
2011-03-15 18:35 ` Jan Kratochvil
2011-03-15 18:48 ` Pedro Alves
2011-03-15 19:28 ` Jan Kratochvil
2011-03-15 20:06 ` Pedro Alves
2011-03-16 10:20 ` Jan Kratochvil
2011-03-16 11:44 ` Pedro Alves
2011-04-17 14:05 ` [patch] [gdbserver] Fix multi-GB error log files [doc review] Jan Kratochvil
2011-04-17 16:31 ` Eli Zaretskii
2011-04-22 21:42 ` Jan Kratochvil
2011-04-23 6:16 ` Eli Zaretskii
2011-04-23 8:00 ` Jan Kratochvil
2011-04-23 11:09 ` Eli Zaretskii
2011-04-24 8:24 ` Jan Kratochvil
2011-04-24 7:35 ` Eli Zaretskii
2011-04-24 8:04 ` [commit] " Jan Kratochvil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox