From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10794 invoked by alias); 31 Jan 2007 14:35:50 -0000 Received: (qmail 10782 invoked by uid 22791); 31 Jan 2007 14:35:49 -0000 X-Spam-Check-By: sourceware.org Received: from main.gmane.org (HELO ciao.gmane.org) (80.91.229.2) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 31 Jan 2007 14:35:42 +0000 Received: from list by ciao.gmane.org with local (Exim 4.43) id 1HCGYK-0006eT-2G for gdb-patches@sources.redhat.com; Wed, 31 Jan 2007 15:35:12 +0100 Received: from 73-198.umostel.ru ([82.179.73.198]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 31 Jan 2007 15:35:12 +0100 Received: from ghost by 73-198.umostel.ru with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 31 Jan 2007 15:35:12 +0100 To: gdb-patches@sources.redhat.com From: Vladimir Prus Subject: Re: "target remote | " stderr Date: Wed, 31 Jan 2007 14:35:00 -0000 Message-ID: References: <200701261653.53834.vladimir@codesourcery.com> <20070126140028.GA29456@nevyn.them.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart1980229.nCBCm2JPNg" Content-Transfer-Encoding: 7Bit User-Agent: KNode/0.10.2 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-01/txt/msg00606.txt.bz2 --nextPart1980229.nCBCm2JPNg Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8Bit Content-length: 1281 Daniel Jacobowitz wrote: >> 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. > > The patch seems OK to me; though I would like to be sure we can > implement this for MinGW before we get too used to the idea. Implementing for MinGW required modifying libiberty so that it can catch stderr to a pipe. Here's a patch for gdb that relies on the libiberty patch. Does this sound OK provided libiberty patch is approved? - 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-mingw.c (pipe_windows_open): Pass PEX_STDERR_TO_PIPE to pex_run. Initialize sd->error_fd. * ser-base.c (generic_readchar): Check if there's anything in stderr channel and route that to gdb_stderr. --nextPart1980229.nCBCm2JPNg Content-Type: text/x-diff; name="remote_stderr_try2__gdb_mainline.diff" Content-Transfer-Encoding: 8Bit Content-Disposition: attachment; filename="remote_stderr_try2__gdb_mainline.diff" Content-length: 5080 --- gdb/serial.c (/patches/gdb/mingw_cpp_declarations/gdb_mainline) (revision 3263) +++ gdb/serial.c (/patches/gdb/remote_stderr_try2/gdb_mainline) (revision 3263) @@ -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 (/patches/gdb/mingw_cpp_declarations/gdb_mainline) (revision 3263) +++ gdb/serial.h (/patches/gdb/remote_stderr_try2/gdb_mainline) (revision 3263) @@ -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 (/patches/gdb/mingw_cpp_declarations/gdb_mainline) (revision 3263) +++ gdb/ser-pipe.c (/patches/gdb/remote_stderr_try2/gdb_mainline) (revision 3263) @@ -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 (/patches/gdb/mingw_cpp_declarations/gdb_mainline) (revision 3263) +++ gdb/ser-base.c (/patches/gdb/remote_stderr_try2/gdb_mainline) (revision 3263) @@ -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; --- gdb/ser-mingw.c (/patches/gdb/mingw_cpp_declarations/gdb_mainline) (revision 3263) +++ gdb/ser-mingw.c (/patches/gdb/remote_stderr_try2/gdb_mainline) (revision 3263) @@ -697,6 +697,7 @@ static int pipe_windows_open (struct serial *scb, const char *name) { struct pipe_state *ps; + FILE *pex_stderr; char **argv = buildargv (name); struct cleanup *back_to = make_cleanup_freeargv (argv); @@ -717,7 +718,8 @@ pipe_windows_open (struct serial *scb, c { int err; const char *err_msg - = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT, + = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT + | PEX_STDERR_TO_PIPE, argv[0], argv, NULL, NULL, &err); @@ -739,8 +741,13 @@ pipe_windows_open (struct serial *scb, c ps->output = pex_read_output (ps->pex, 1); if (! ps->output) goto fail; - scb->fd = fileno (ps->output); + + pex_stderr = pex_read_err (ps->pex, 1); + if (! pex_stderr) + goto fail; + scb->error_fd = fileno (pex_stderr); + scb->state = (void *) ps; discard_cleanups (back_to); Property changes on: ___________________________________________________________________ Name: csl:base +/all/patches/gdb/mingw_cpp_declarations/gdb_mainline --nextPart1980229.nCBCm2JPNg--