From: Vladimir Prus <vladimir@codesourcery.com>
To: gdb-patches@sources.redhat.com
Subject: "target remote | " stderr
Date: Fri, 26 Jan 2007 13:54:00 -0000 [thread overview]
Message-ID: <200701261653.53834.vladimir@codesourcery.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 735 bytes --]
At the moment, when handling
target remote | whatever
gdb does not do anything with 'whatever''s stderr. This is not good,
because when using MI, frontend might not even look at stderr at all,
so messages from 'whatever' get lost.
This patch fixes that. The fix is only for Linux, I plan to do the
same with mingw support, but only if this patch is considered OK.
- Volodya
Pass stderr of program run with "target remote |"
via gdb_stderr.
* serial.c (serial_open): Set error_fd to -1.
* serial.h (struct serial): New field error_fd.
* ser-pipe.c (pipe_open): Create another pair
of sockets. Pass stderr to gdb.
* ser-base.c (generic_readchar): Check if there's
anything in stderr channel and route that to gdb_stderr.
[-- Attachment #2: remote_stderr__gdb_mainline.diff --]
[-- Type: text/x-diff, Size: 3660 bytes --]
--- gdb/serial.c (/mirrors/gdb_mainline) (revision 3222)
+++ gdb/serial.c (/patches/gdb/remote_stderr/gdb_mainline) (revision 3222)
@@ -211,6 +211,7 @@ serial_open (const char *name)
scb->bufcnt = 0;
scb->bufp = scb->buf;
+ scb->error_fd = -1;
if (scb->ops->open (scb, open_name))
{
--- gdb/serial.h (/mirrors/gdb_mainline) (revision 3222)
+++ gdb/serial.h (/patches/gdb/remote_stderr/gdb_mainline) (revision 3222)
@@ -191,6 +191,12 @@ extern int serial_debug_p (struct serial
struct serial
{
int fd; /* File descriptor */
+ int error_fd; /* File descriptor for a separate
+ error stream that should be
+ immediately forwarded to gdb_stderr.
+ This may be -1.
+ If != -1, this descriptor should
+ be non-blocking. */
struct serial_ops *ops; /* Function vector */
void *state; /* Local context info for open FD */
serial_ttystate ttystate; /* Not used (yet) */
--- gdb/ser-pipe.c (/mirrors/gdb_mainline) (revision 3222)
+++ gdb/ser-pipe.c (/patches/gdb/remote_stderr/gdb_mainline) (revision 3222)
@@ -62,9 +62,12 @@ pipe_open (struct serial *scb, const cha
* published in UNIX Review, Vol. 6, No. 8.
*/
int pdes[2];
+ int err_pdes[2];
int pid;
if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
return -1;
+ if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
+ return -1;
/* Create the child process to run the command in. Note that the
apparent call to vfork() below *might* actually be a call to
@@ -77,9 +80,18 @@ pipe_open (struct serial *scb, const cha
{
close (pdes[0]);
close (pdes[1]);
+ close (err_pdes[0]);
+ close (err_pdes[1]);
return -1;
}
+ if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
+ {
+ close (err_pdes[0]);
+ close (err_pdes[1]);
+ err_pdes[0] = err_pdes[1] = -1;
+ }
+
/* Child. */
if (pid == 0)
{
@@ -91,6 +103,13 @@ pipe_open (struct serial *scb, const cha
close (pdes[1]);
}
dup2 (STDOUT_FILENO, STDIN_FILENO);
+
+ if (err_pdes[0] != -1)
+ {
+ close (err_pdes[0]);
+ dup2 (err_pdes[1], STDERR_FILENO);
+ close (err_pdes[1]);
+ }
#if 0
/* close any stray FD's - FIXME - how? */
/* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
@@ -109,6 +128,7 @@ pipe_open (struct serial *scb, const cha
state = XMALLOC (struct pipe_state);
state->pid = pid;
scb->fd = pdes[0];
+ scb->error_fd = err_pdes[0];
scb->state = state;
/* If we don't do this, GDB simply exits when the remote side dies. */
--- gdb/ser-base.c (/mirrors/gdb_mainline) (revision 3222)
+++ gdb/ser-base.c (/patches/gdb/remote_stderr/gdb_mainline) (revision 3222)
@@ -314,6 +314,33 @@ generic_readchar (struct serial *scb, in
int (do_readchar) (struct serial *scb, int timeout))
{
int ch;
+
+ /* Read any error output we might have. */
+ if (scb->error_fd != -1)
+ {
+ ssize_t s;
+ char buf[81];
+ while ((s = read (scb->error_fd, &buf, 80)) > 0)
+ {
+ char *current;
+ char *newline;
+ /* In theory, embedded newlines are not a problem.
+ But for MI, we want each output line to have just
+ one newline for legibility. So output things
+ in newline chunks. */
+ buf[s] = '\0';
+ current = buf;
+ while ((newline = strstr (current, "\n")) != NULL)
+ {
+ *newline = '\0';
+ fputs_unfiltered (current, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ current = newline + 1;
+ }
+ fputs_unfiltered (current, gdb_stderr);
+ }
+ }
+
if (scb->bufcnt > 0)
{
ch = *scb->bufp;
next reply other threads:[~2007-01-26 13:54 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-26 13:54 Vladimir Prus [this message]
2007-01-26 14:00 ` Daniel Jacobowitz
2007-01-31 14:35 ` Vladimir Prus
2007-01-31 14:41 ` Daniel Jacobowitz
2007-02-11 16:56 ` Vladimir Prus
2007-02-11 18:10 ` Mark Kettenis
2007-02-17 7:50 ` Vladimir Prus
2007-02-11 20:24 ` Eli Zaretskii
2007-02-17 7:35 ` Vladimir Prus
2007-02-17 10:56 ` Eli Zaretskii
2007-02-17 14:31 ` Vladimir Prus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200701261653.53834.vladimir@codesourcery.com \
--to=vladimir@codesourcery.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox