* [RFA] stdio gdbserver
@ 2011-12-01 21:26 Doug Evans
2011-12-02 9:19 ` Eli Zaretskii
2011-12-02 16:35 ` Tom Tromey
0 siblings, 2 replies; 4+ messages in thread
From: Doug Evans @ 2011-12-01 21:26 UTC (permalink / raw)
To: gdb-patches
Hi.
This patch adds stdio support to gdbserver.
It's a revamp of a patch I submitted a fair while ago.
E.g. target remote | ssh hostname gdbserver - hello
Ok to check in?
I also have a board description file akin to native-gdbserver
that lets me run the testsuite with it.
I'll add that to the wiki alongside the one for native-gdbserver
after this goes in.
2011-12-01 Doug Evans <dje@google.com>
* NEWS: Add entry for stdio gdbserver.
gdbserver/
* linux-low.c (linux_create_inferior): If stdio connection,
redirect stdin from /dev/null, stdout to stderr.
* remote-utils.c (remote_is_stdio): New static global.
(remote_connection_is_stdio): New function.
(remote_prepare): Handle stdio connection.
(remote_open): Ditto.
(remote_close): Don't close stdin for stdio connections.
(read_prim,write_prim): New functions. Replace all calls to
read/write to these.
* server.c (main): Watch for "-" argument. Move call to
remote_prepare before start_inferior. If client closes connection,
exit if stdio connection. Add debugging printf.
* server.h (STDIO_CONNECTION_NAME): New macro.
(remote_connection_is_stdio): Declare.
doc/
* gdb.texinfo (Server): Document -/stdio argument to gdbserver.
testsuite/
* lib/gdbserver-support.exp (gdbserver_default_get_remote_address): New
function.
(gdbserver_start): Call gdb,get_remote_address to compute argument
to "target remote" command.
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.469
diff -u -p -r1.469 NEWS
--- NEWS 20 Nov 2011 23:59:47 -0000 1.469
+++ NEWS 1 Dec 2011 21:14:00 -0000
@@ -3,6 +3,9 @@
*** Changes since GDB 7.3.1
+* GDBserver now supports stdio connections.
+ E.g. (gdb) target remote | ssh myhost gdbserver - hello
+
* GDB now allows you to skip uninteresting functions and files when
stepping with the "skip function" and "skip file" commands.
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.901
diff -u -p -r1.901 gdb.texinfo
--- doc/gdb.texinfo 22 Nov 2011 21:25:18 -0000 1.901
+++ doc/gdb.texinfo 1 Dec 2011 21:14:00 -0000
@@ -16767,8 +16767,10 @@ syntax is:
target> gdbserver @var{comm} @var{program} [ @var{args} @dots{} ]
@end smallexample
-@var{comm} is either a device name (to use a serial line) or a TCP
-hostname and portnumber. For example, to debug Emacs with the argument
+@var{comm} is either a device name (to use a serial line), or a TCP
+hostname and portnumber, or @code{-} or @code{stdio} to use
+stdin/stdout of @code{gdbserver}.
+For example, to debug Emacs with the argument
@samp{foo.txt} and communicate with @value{GDBN} over the serial port
@file{/dev/com1}:
@@ -16797,6 +16799,23 @@ conflicts with another service, @code{gd
and exits.} You must use the same port number with the host @value{GDBN}
@code{target remote} command.
+The @code{stdio} connection is useful when starting @code{gdbserver}
+with ssh:
+
+@smallexample
+(gdb) target remote | ssh -T hostname gdbserver - hello
+@end smallexample
+
+The @samp{-T} option to ssh is provided because we don't need a remote pty,
+and we don't want escape-character handling. Ssh does this by default when
+a command is provided, the flag is provided to make it explicit.
+It can be omitted if you want to.
+
+Programs started with stdio-connected gdbserver have @file{/dev/null} for
+@code{stdin}, and @code{stdout} is redirected to @code{stderr}.
+This is done so that inferior I/O doesn't interfere with
+@value{GDBN}/gdbserver communication.
+
@subsubsection Attaching to a Running Program
@cindex attach to a program, @code{gdbserver}
@cindex @option{--attach}, @code{gdbserver} option
Index: gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.179
diff -u -p -r1.179 linux-low.c
--- gdbserver/linux-low.c 14 Nov 2011 20:07:24 -0000 1.179
+++ gdbserver/linux-low.c 1 Dec 2011 21:14:00 -0000
@@ -569,6 +569,18 @@ linux_create_inferior (char *program, ch
setpgid (0, 0);
+ /* If gdbserver is connected to gdb via stdio, redirect the inferior's
+ stdout to stderr so that inferior i/o doesn't corrupt the connection.
+ Also, redirect stdin to /dev/null. */
+ if (remote_connection_is_stdio ())
+ {
+ close (0);
+ open ("/dev/null", O_RDONLY);
+ dup2 (2, 1);
+ write (2, "stdin/stdout redirected\n",
+ sizeof ("stdin/stdout redirected\n") - 1);
+ }
+
execv (program, allargs);
if (errno == ENOENT)
execvp (program, allargs);
Index: gdbserver/remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.88
diff -u -p -r1.88 remote-utils.c
--- gdbserver/remote-utils.c 9 Nov 2011 02:32:42 -0000 1.88
+++ gdbserver/remote-utils.c 1 Dec 2011 21:14:00 -0000
@@ -107,6 +107,8 @@ struct sym_cache
int remote_debug = 0;
struct ui_file *gdb_stdlog;
+static int remote_is_stdio = 0;
+
static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR;
static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
@@ -130,6 +132,14 @@ gdb_connected (void)
return remote_desc != INVALID_DESCRIPTOR;
}
+/* Return true if the remote connection is over stdio. */
+
+int
+remote_connection_is_stdio (void)
+{
+ return remote_is_stdio;
+}
+
static void
enable_async_notification (int fd)
{
@@ -222,6 +232,16 @@ remote_prepare (char *name)
socklen_t tmp;
char *port_end;
+ if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+ {
+ /* We need to record fact that we're using stdio sooner than the
+ call to remote_open so start_inferior knows the connection is
+ via stdio. */
+ remote_is_stdio = 1;
+ transport_is_reliable = 1;
+ return;
+ }
+
port_str = strchr (name, ':');
if (port_str == NULL)
{
@@ -272,11 +292,27 @@ remote_open (char *name)
char *port_str;
port_str = strchr (name, ':');
+#ifdef USE_WIN32API
if (port_str == NULL)
+ error ("Only <host>:<port> is supported on this platform.");
+#endif
+
+ if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+ {
+ fprintf (stderr, "Remote debugging using stdio\n");
+
+ /* Use stdin as the handle of the connection.
+ We only select on reads, for example. */
+ remote_desc = fileno (stdin);
+
+ enable_async_notification (remote_desc);
+
+ /* Register the event loop handler. */
+ add_file_handler (remote_desc, handle_serial_event, NULL);
+ }
+#ifndef USE_WIN32API
+ else if (port_str == NULL)
{
-#ifdef USE_WIN32API
- error ("Only <host>:<port> is supported on this platform.");
-#else
struct stat statbuf;
if (stat (name, &statbuf) == 0
@@ -341,8 +377,8 @@ remote_open (char *name)
/* Register the event loop handler. */
add_file_handler (remote_desc, handle_serial_event, NULL);
-#endif /* USE_WIN32API */
}
+#endif /* ! USE_WIN32API */
else
{
int port;
@@ -372,7 +408,8 @@ remote_close (void)
#ifdef USE_WIN32API
closesocket (remote_desc);
#else
- close (remote_desc);
+ if (! remote_connection_is_stdio ())
+ close (remote_desc);
#endif
remote_desc = INVALID_DESCRIPTOR;
@@ -731,6 +768,32 @@ read_ptid (char *buf, char **obuf)
return ptid_build (pid, tid, 0);
}
+/* Write COUNT bytes in BUF to the client.
+ The result is the number of bytes written or -1 if error.
+ This may return less than COUNT. */
+
+static int
+write_prim (const void *buf, int count)
+{
+ if (remote_connection_is_stdio ())
+ return write (fileno (stdout), buf, count);
+ else
+ return write (remote_desc, buf, count);
+}
+
+/* Read COUNT bytes from the client and store in BUF.
+ The result is the number of bytes read or -1 if error.
+ This may return less than COUNT. */
+
+static int
+read_prim (void *buf, int count)
+{
+ if (remote_connection_is_stdio ())
+ return read (fileno (stdin), buf, count);
+ else
+ return read (remote_desc, buf, count);
+}
+
/* Send a packet to the remote machine, with error checking.
The data of the packet is in BUF, and the length of the
packet is in CNT. Returns >= 0 on success, -1 otherwise. */
@@ -768,7 +831,7 @@ putpkt_binary_1 (char *buf, int cnt, int
do
{
- if (write (remote_desc, buf2, p - buf2) != p - buf2)
+ if (write_prim (buf2, p - buf2) != p - buf2)
{
perror ("putpkt(write)");
free (buf2);
@@ -863,7 +926,7 @@ input_interrupt (int unused)
int cc;
char c = 0;
- cc = read (remote_desc, &c, 1);
+ cc = read_prim (&c, 1);
if (cc != 1 || c != '\003' || current_inferior == NULL)
{
@@ -991,8 +1054,7 @@ readchar (void)
if (readchar_bufcnt == 0)
{
- readchar_bufcnt = read (remote_desc, readchar_buf,
- sizeof (readchar_buf));
+ readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
if (readchar_bufcnt <= 0)
{
@@ -1114,7 +1176,7 @@ getpkt (char *buf)
fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
(c1 << 4) + c2, csum, buf);
- if (write (remote_desc, "-", 1) != 1)
+ if (write_prim ("-", 1) != 1)
return -1;
}
@@ -1126,7 +1188,7 @@ getpkt (char *buf)
fflush (stderr);
}
- if (write (remote_desc, "+", 1) != 1)
+ if (write_prim ("+", 1) != 1)
return -1;
if (remote_debug)
Index: gdbserver/server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.151
diff -u -p -r1.151 server.c
--- gdbserver/server.c 14 Nov 2011 15:18:51 -0000 1.151
+++ gdbserver/server.c 1 Dec 2011 21:14:00 -0000
@@ -2579,6 +2579,13 @@ main (int argc, char *argv[])
}
}
}
+ else if (strcmp (*next_arg, "-") == 0)
+ {
+ /* "-" specifies a stdio connection and is a form of port
+ specification. */
+ *next_arg = STDIO_CONNECTION_NAME;
+ break;
+ }
else if (strcmp (*next_arg, "--disable-randomization") == 0)
disable_randomization = 1;
else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
@@ -2609,6 +2616,12 @@ main (int argc, char *argv[])
exit (1);
}
+ /* We need to know whether the remote connection is stdio before
+ starting the inferior. Inferiors created in this scenario have
+ stdin,stdout redirected. So do this here before we call
+ start_inferior. */
+ remote_prepare (port);
+
bad_attach = 0;
pid = 0;
@@ -2696,8 +2709,6 @@ main (int argc, char *argv[])
exit (1);
}
- remote_prepare (port);
-
while (1)
{
noack_mode = 0;
@@ -2723,11 +2734,17 @@ main (int argc, char *argv[])
/* If an exit was requested (using the "monitor exit" command),
terminate now. The only other way to get here is for
- getpkt to fail; close the connection and reopen it at the
+ getpkt to fail; if the connection is via stdio terminate now,
+ otherwise close the connection and reopen it at the
top of the loop. */
- if (exit_requested || run_once)
- {
+ if (exit_requested
+ || run_once
+ || remote_connection_is_stdio ())
+ {
+ if (debug_threads)
+ fprintf (stderr, "Remote side has terminated connection. "
+ "Shutting down.\n");
detach_or_kill_for_exit ();
exit (0);
}
Index: gdbserver/server.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.h,v
retrieving revision 1.88
diff -u -p -r1.88 server.h
--- gdbserver/server.h 14 Nov 2011 20:07:24 -0000 1.88
+++ gdbserver/server.h 1 Dec 2011 21:14:00 -0000
@@ -342,6 +342,9 @@ extern int transport_is_reliable;
int gdb_connected (void);
+#define STDIO_CONNECTION_NAME "stdio"
+int remote_connection_is_stdio (void);
+
ptid_t read_ptid (char *buf, char **obuf);
char *write_ptid (char *buf, ptid_t ptid);
Index: testsuite/lib/gdbserver-support.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdbserver-support.exp,v
retrieving revision 1.20
diff -u -p -r1.20 gdbserver-support.exp
--- testsuite/lib/gdbserver-support.exp 20 Nov 2011 23:59:49 -0000 1.20
+++ testsuite/lib/gdbserver-support.exp 1 Dec 2011 21:14:00 -0000
@@ -179,6 +179,12 @@ proc gdbserver_download_current_prog { }
return $gdbserver_server_exec
}
+# Default routine to compute the argument to "target remote".
+
+proc gdbserver_default_get_remote_address { host port } {
+ return "$host$port"
+}
+
# Start a gdbserver process with initial OPTIONS and trailing ARGUMENTS.
# The port will be filled in between them automatically.
#
@@ -202,6 +208,15 @@ proc gdbserver_start { options arguments
set debughost "localhost:"
}
+ # Some boards use a different value for the port that is passed to
+ # gdbserver and the port that is passed to the "target remote" command.
+ # One example is the stdio gdbserver support.
+ if [target_info exists gdb,get_remote_address] {
+ set get_remote_address [target_info gdb,get_remote_address]
+ } else {
+ set get_remote_address gdbserver_default_get_remote_address
+ }
+
# Extract the protocol
if [target_info exists gdb_protocol] {
set protocol [target_info gdb_protocol]
@@ -213,9 +228,6 @@ proc gdbserver_start { options arguments
# Loop till we find a free port.
while 1 {
- # Export the host:port pair.
- set gdbport $debughost$portnum
-
# Fire off the debug agent.
set gdbserver_command "$gdbserver"
@@ -231,9 +243,9 @@ proc gdbserver_start { options arguments
if { $options != "" } {
append gdbserver_command " $options"
}
-
- append gdbserver_command " :$portnum"
-
+ if { $portnum != "" } {
+ append gdbserver_command " :$portnum"
+ }
if { $arguments != "" } {
append gdbserver_command " $arguments"
}
@@ -271,7 +283,7 @@ proc gdbserver_start { options arguments
}
}
- return [list $protocol $gdbport]
+ return [list $protocol [$get_remote_address $debughost $portnum]]
}
# Start a gdbserver process running SERVER_EXEC, and connect GDB
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA] stdio gdbserver
2011-12-01 21:26 [RFA] stdio gdbserver Doug Evans
@ 2011-12-02 9:19 ` Eli Zaretskii
2011-12-02 16:35 ` Tom Tromey
1 sibling, 0 replies; 4+ messages in thread
From: Eli Zaretskii @ 2011-12-02 9:19 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
> Date: Thu, 1 Dec 2011 13:26:32 -0800 (PST)
> From: dje@google.com (Doug Evans)
>
> This patch adds stdio support to gdbserver.
> It's a revamp of a patch I submitted a fair while ago.
>
> E.g. target remote | ssh hostname gdbserver - hello
>
> Ok to check in?
OK for the documentation parts.
Thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA] stdio gdbserver
2011-12-01 21:26 [RFA] stdio gdbserver Doug Evans
2011-12-02 9:19 ` Eli Zaretskii
@ 2011-12-02 16:35 ` Tom Tromey
2011-12-16 19:15 ` Doug Evans
1 sibling, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2011-12-02 16:35 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
>>>>> "Doug" == Doug Evans <dje@google.com> writes:
Doug> This patch adds stdio support to gdbserver.
Doug> It's a revamp of a patch I submitted a fair while ago.
Doug> E.g. target remote | ssh hostname gdbserver - hello
Doug> Ok to check in?
I read the patch, and it seemed reasonable to me; but I don't know
gdbserver very well.
I like this idea though.
Doug> I also have a board description file akin to native-gdbserver
Doug> that lets me run the testsuite with it.
Doug> I'll add that to the wiki alongside the one for native-gdbserver
Doug> after this goes in.
Can we check it in?
It seems to me that there are a few board files like this that are
fairly generic and that would be beneficial to have right at hand.
Tom
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA] stdio gdbserver
2011-12-02 16:35 ` Tom Tromey
@ 2011-12-16 19:15 ` Doug Evans
0 siblings, 0 replies; 4+ messages in thread
From: Doug Evans @ 2011-12-16 19:15 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1656 bytes --]
On Fri, Dec 2, 2011 at 8:35 AM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Doug" == Doug Evans <dje@google.com> writes:
>
> Doug> This patch adds stdio support to gdbserver.
> Doug> It's a revamp of a patch I submitted a fair while ago.
> Doug> E.g. target remote | ssh hostname gdbserver - hello
> Doug> Ok to check in?
>
> I read the patch, and it seemed reasonable to me; but I don't know
> gdbserver very well.
>
> I like this idea though.
Here is what I committed.
2011-12-16 Doug Evans <dje@google.com>
* NEWS: Add entry for stdio gdbserver.
gdbserver/
* linux-low.c (linux_create_inferior): If stdio connection,
redirect stdin from /dev/null, stdout to stderr.
* remote-utils.c (remote_is_stdio): New static global.
(remote_connection_is_stdio): New function.
(remote_prepare): Handle stdio connection.
(remote_open): Ditto.
(remote_close): Don't close stdin for stdio connections.
(read_prim,write_prim): New functions. Replace all calls to
read/write to these.
* server.c (main): Watch for "-" argument. Move call to
remote_prepare before start_inferior.
* server.h (STDIO_CONNECTION_NAME): New macro.
(remote_connection_is_stdio): Declare.
doc/
* gdb.texinfo (Server): Document -/stdio argument to
gdbserver.
testsuite/
* lib/gdbserver-support.exp (gdb_target_cmd): Recognize stdio
gdbserver output.
(gdbserver_default_get_remote_address): New function.
(gdbserver_start): Call gdb,get_remote_address to compute
argument
to "target remote" command.
[-- Attachment #2: gdb-111216-gdbserver-stdio-4.patch.txt --]
[-- Type: text/plain, Size: 13514 bytes --]
2011-12-16 Doug Evans <dje@google.com>
* NEWS: Add entry for stdio gdbserver.
gdbserver/
* linux-low.c (linux_create_inferior): If stdio connection,
redirect stdin from /dev/null, stdout to stderr.
* remote-utils.c (remote_is_stdio): New static global.
(remote_connection_is_stdio): New function.
(remote_prepare): Handle stdio connection.
(remote_open): Ditto.
(remote_close): Don't close stdin for stdio connections.
(read_prim,write_prim): New functions. Replace all calls to
read/write to these.
* server.c (main): Watch for "-" argument. Move call to
remote_prepare before start_inferior.
* server.h (STDIO_CONNECTION_NAME): New macro.
(remote_connection_is_stdio): Declare.
doc/
* gdb.texinfo (Server): Document -/stdio argument to gdbserver.
testsuite/
* lib/gdbserver-support.exp (gdb_target_cmd): Recognize stdio
gdbserver output.
(gdbserver_default_get_remote_address): New function.
(gdbserver_start): Call gdb,get_remote_address to compute argument
to "target remote" command.
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.475
diff -u -p -r1.475 NEWS
--- NEWS 16 Dec 2011 15:55:38 -0000 1.475
+++ NEWS 16 Dec 2011 18:33:35 -0000
@@ -3,6 +3,9 @@
*** Changes since GDB 7.4
+* GDBserver now supports stdio connections.
+ E.g. (gdb) target remote | ssh myhost gdbserver - hello
+
*** Changes in GDB 7.4
* GDB now handles ambiguous linespecs more consistently; the existing
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.906
diff -u -p -r1.906 gdb.texinfo
--- doc/gdb.texinfo 16 Dec 2011 15:55:38 -0000 1.906
+++ doc/gdb.texinfo 16 Dec 2011 18:33:36 -0000
@@ -16766,8 +16766,10 @@ syntax is:
target> gdbserver @var{comm} @var{program} [ @var{args} @dots{} ]
@end smallexample
-@var{comm} is either a device name (to use a serial line) or a TCP
-hostname and portnumber. For example, to debug Emacs with the argument
+@var{comm} is either a device name (to use a serial line), or a TCP
+hostname and portnumber, or @code{-} or @code{stdio} to use
+stdin/stdout of @code{gdbserver}.
+For example, to debug Emacs with the argument
@samp{foo.txt} and communicate with @value{GDBN} over the serial port
@file{/dev/com1}:
@@ -16796,6 +16798,23 @@ conflicts with another service, @code{gd
and exits.} You must use the same port number with the host @value{GDBN}
@code{target remote} command.
+The @code{stdio} connection is useful when starting @code{gdbserver}
+with ssh:
+
+@smallexample
+(gdb) target remote | ssh -T hostname gdbserver - hello
+@end smallexample
+
+The @samp{-T} option to ssh is provided because we don't need a remote pty,
+and we don't want escape-character handling. Ssh does this by default when
+a command is provided, the flag is provided to make it explicit.
+You could elide it if you want to.
+
+Programs started with stdio-connected gdbserver have @file{/dev/null} for
+@code{stdin}, and @code{stdout},@code{stderr} are sent back to gdb for
+display through a pipe connected to gdbserver.
+Both @code{stdout} and @code{stderr} use the same pipe.
+
@subsubsection Attaching to a Running Program
@cindex attach to a program, @code{gdbserver}
@cindex @option{--attach}, @code{gdbserver} option
Index: gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.184
diff -u -p -r1.184 linux-low.c
--- gdbserver/linux-low.c 14 Dec 2011 17:33:24 -0000 1.184
+++ gdbserver/linux-low.c 16 Dec 2011 18:33:36 -0000
@@ -569,6 +569,18 @@ linux_create_inferior (char *program, ch
setpgid (0, 0);
+ /* If gdbserver is connected to gdb via stdio, redirect the inferior's
+ stdout to stderr so that inferior i/o doesn't corrupt the connection.
+ Also, redirect stdin to /dev/null. */
+ if (remote_connection_is_stdio ())
+ {
+ close (0);
+ open ("/dev/null", O_RDONLY);
+ dup2 (2, 1);
+ write (2, "stdin/stdout redirected\n",
+ sizeof ("stdin/stdout redirected\n") - 1);
+ }
+
execv (program, allargs);
if (errno == ENOENT)
execvp (program, allargs);
Index: gdbserver/remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.88
diff -u -p -r1.88 remote-utils.c
--- gdbserver/remote-utils.c 9 Nov 2011 02:32:42 -0000 1.88
+++ gdbserver/remote-utils.c 16 Dec 2011 18:33:36 -0000
@@ -107,6 +107,8 @@ struct sym_cache
int remote_debug = 0;
struct ui_file *gdb_stdlog;
+static int remote_is_stdio = 0;
+
static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR;
static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
@@ -130,6 +132,14 @@ gdb_connected (void)
return remote_desc != INVALID_DESCRIPTOR;
}
+/* Return true if the remote connection is over stdio. */
+
+int
+remote_connection_is_stdio (void)
+{
+ return remote_is_stdio;
+}
+
static void
enable_async_notification (int fd)
{
@@ -222,6 +232,17 @@ remote_prepare (char *name)
socklen_t tmp;
char *port_end;
+ remote_is_stdio = 0;
+ if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+ {
+ /* We need to record fact that we're using stdio sooner than the
+ call to remote_open so start_inferior knows the connection is
+ via stdio. */
+ remote_is_stdio = 1;
+ transport_is_reliable = 1;
+ return;
+ }
+
port_str = strchr (name, ':');
if (port_str == NULL)
{
@@ -272,11 +293,27 @@ remote_open (char *name)
char *port_str;
port_str = strchr (name, ':');
+#ifdef USE_WIN32API
if (port_str == NULL)
+ error ("Only <host>:<port> is supported on this platform.");
+#endif
+
+ if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+ {
+ fprintf (stderr, "Remote debugging using stdio\n");
+
+ /* Use stdin as the handle of the connection.
+ We only select on reads, for example. */
+ remote_desc = fileno (stdin);
+
+ enable_async_notification (remote_desc);
+
+ /* Register the event loop handler. */
+ add_file_handler (remote_desc, handle_serial_event, NULL);
+ }
+#ifndef USE_WIN32API
+ else if (port_str == NULL)
{
-#ifdef USE_WIN32API
- error ("Only <host>:<port> is supported on this platform.");
-#else
struct stat statbuf;
if (stat (name, &statbuf) == 0
@@ -341,8 +378,8 @@ remote_open (char *name)
/* Register the event loop handler. */
add_file_handler (remote_desc, handle_serial_event, NULL);
-#endif /* USE_WIN32API */
}
+#endif /* USE_WIN32API */
else
{
int port;
@@ -372,7 +409,8 @@ remote_close (void)
#ifdef USE_WIN32API
closesocket (remote_desc);
#else
- close (remote_desc);
+ if (! remote_connection_is_stdio ())
+ close (remote_desc);
#endif
remote_desc = INVALID_DESCRIPTOR;
@@ -731,6 +769,32 @@ read_ptid (char *buf, char **obuf)
return ptid_build (pid, tid, 0);
}
+/* Write COUNT bytes in BUF to the client.
+ The result is the number of bytes written or -1 if error.
+ This may return less than COUNT. */
+
+static int
+write_prim (const void *buf, int count)
+{
+ if (remote_connection_is_stdio ())
+ return write (fileno (stdout), buf, count);
+ else
+ return write (remote_desc, buf, count);
+}
+
+/* Read COUNT bytes from the client and store in BUF.
+ The result is the number of bytes read or -1 if error.
+ This may return less than COUNT. */
+
+static int
+read_prim (void *buf, int count)
+{
+ if (remote_connection_is_stdio ())
+ return read (fileno (stdin), buf, count);
+ else
+ return read (remote_desc, buf, count);
+}
+
/* Send a packet to the remote machine, with error checking.
The data of the packet is in BUF, and the length of the
packet is in CNT. Returns >= 0 on success, -1 otherwise. */
@@ -768,7 +832,7 @@ putpkt_binary_1 (char *buf, int cnt, int
do
{
- if (write (remote_desc, buf2, p - buf2) != p - buf2)
+ if (write_prim (buf2, p - buf2) != p - buf2)
{
perror ("putpkt(write)");
free (buf2);
@@ -863,7 +927,7 @@ input_interrupt (int unused)
int cc;
char c = 0;
- cc = read (remote_desc, &c, 1);
+ cc = read_prim (&c, 1);
if (cc != 1 || c != '\003' || current_inferior == NULL)
{
@@ -991,8 +1055,7 @@ readchar (void)
if (readchar_bufcnt == 0)
{
- readchar_bufcnt = read (remote_desc, readchar_buf,
- sizeof (readchar_buf));
+ readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
if (readchar_bufcnt <= 0)
{
@@ -1114,7 +1177,7 @@ getpkt (char *buf)
fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
(c1 << 4) + c2, csum, buf);
- if (write (remote_desc, "-", 1) != 1)
+ if (write_prim ("-", 1) != 1)
return -1;
}
@@ -1126,7 +1189,7 @@ getpkt (char *buf)
fflush (stderr);
}
- if (write (remote_desc, "+", 1) != 1)
+ if (write_prim ("+", 1) != 1)
return -1;
if (remote_debug)
Index: gdbserver/server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.152
diff -u -p -r1.152 server.c
--- gdbserver/server.c 2 Dec 2011 22:26:53 -0000 1.152
+++ gdbserver/server.c 16 Dec 2011 18:33:36 -0000
@@ -2606,6 +2606,13 @@ main (int argc, char *argv[])
}
}
}
+ else if (strcmp (*next_arg, "-") == 0)
+ {
+ /* "-" specifies a stdio connection and is a form of port
+ specification. */
+ *next_arg = STDIO_CONNECTION_NAME;
+ break;
+ }
else if (strcmp (*next_arg, "--disable-randomization") == 0)
disable_randomization = 1;
else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
@@ -2636,6 +2643,12 @@ main (int argc, char *argv[])
exit (1);
}
+ /* We need to know whether the remote connection is stdio before
+ starting the inferior. Inferiors created in this scenario have
+ stdin,stdout redirected. So do this here before we call
+ start_inferior. */
+ remote_prepare (port);
+
bad_attach = 0;
pid = 0;
@@ -2723,8 +2736,6 @@ main (int argc, char *argv[])
exit (1);
}
- remote_prepare (port);
-
while (1)
{
noack_mode = 0;
Index: gdbserver/server.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.h,v
retrieving revision 1.88
diff -u -p -r1.88 server.h
--- gdbserver/server.h 14 Nov 2011 20:07:24 -0000 1.88
+++ gdbserver/server.h 16 Dec 2011 18:33:36 -0000
@@ -342,6 +342,9 @@ extern int transport_is_reliable;
int gdb_connected (void);
+#define STDIO_CONNECTION_NAME "stdio"
+int remote_connection_is_stdio (void);
+
ptid_t read_ptid (char *buf, char **obuf);
char *write_ptid (char *buf, ptid_t ptid);
Index: testsuite/lib/gdbserver-support.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdbserver-support.exp,v
retrieving revision 1.21
diff -u -p -r1.21 gdbserver-support.exp
--- testsuite/lib/gdbserver-support.exp 3 Dec 2011 20:20:29 -0000 1.21
+++ testsuite/lib/gdbserver-support.exp 16 Dec 2011 18:33:36 -0000
@@ -70,6 +70,10 @@ proc gdb_target_cmd { targetname serialp
verbose "Set target to $targetname"
return 0
}
+ -re "Remote debugging using stdio.*$gdb_prompt $" {
+ verbose "Set target to $targetname"
+ return 0
+ }
-re "Remote target $targetname connected to.*$gdb_prompt $" {
verbose "Set target to $targetname"
return 0
@@ -183,6 +187,12 @@ proc gdbserver_download_current_prog { }
return $gdbserver_server_exec
}
+# Default routine to compute the argument to "target remote".
+
+proc gdbserver_default_get_remote_address { host port } {
+ return "$host$port"
+}
+
# Start a gdbserver process with initial OPTIONS and trailing ARGUMENTS.
# The port will be filled in between them automatically.
#
@@ -206,6 +216,15 @@ proc gdbserver_start { options arguments
set debughost "localhost:"
}
+ # Some boards use a different value for the port that is passed to
+ # gdbserver and the port that is passed to the "target remote" command.
+ # One example is the stdio gdbserver support.
+ if [target_info exists gdb,get_remote_address] {
+ set get_remote_address [target_info gdb,get_remote_address]
+ } else {
+ set get_remote_address gdbserver_default_get_remote_address
+ }
+
# Extract the protocol
if [target_info exists gdb_protocol] {
set protocol [target_info gdb_protocol]
@@ -217,9 +236,6 @@ proc gdbserver_start { options arguments
# Loop till we find a free port.
while 1 {
- # Export the host:port pair.
- set gdbport $debughost$portnum
-
# Fire off the debug agent.
set gdbserver_command "$gdbserver"
@@ -235,9 +251,9 @@ proc gdbserver_start { options arguments
if { $options != "" } {
append gdbserver_command " $options"
}
-
- append gdbserver_command " :$portnum"
-
+ if { $portnum != "" } {
+ append gdbserver_command " :$portnum"
+ }
if { $arguments != "" } {
append gdbserver_command " $arguments"
}
@@ -275,7 +291,7 @@ proc gdbserver_start { options arguments
}
}
- return [list $protocol $gdbport]
+ return [list $protocol [$get_remote_address $debughost $portnum]]
}
# Start a gdbserver process running SERVER_EXEC, and connect GDB
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-12-16 19:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-01 21:26 [RFA] stdio gdbserver Doug Evans
2011-12-02 9:19 ` Eli Zaretskii
2011-12-02 16:35 ` Tom Tromey
2011-12-16 19:15 ` Doug Evans
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).