Community
Participate
Working Groups
Build Identifier: M20100909-0800 After multiple executions of fprintf(stderr, "some string\n") in user code, the gdb process stderr buffer gets full and further writes to stderr hang gdb. Reproducible: Always
Created attachment 180715 [details] CDT 7.0.1 patch
The attached patch adds a command processor to read from the gdb process error stream. Stderr output is shown in the Console View.
Code to demonstrate problem : #include <stdio.h> #include <stdlib.h> int main(void) { int i = 0; setvbuf(stderr, NULL, _IONBF, 0); for (i = 0; i < 50000; i++) { printf("iteration %d\n", i); // On iteration 14, stepping the following line will leave debugger in run state. fprintf(stderr, "!!!Hello World!!!!!!Hello World!!!\n"); } return EXIT_SUCCESS; }
Very similar to bug 270369 in CDI.
This works ok on Linux. Maybe because we can use PTYs. I'll try it from home, on a Windows machine.
I can see this on Windows. The patch seems to fix the problem, but I find the behavior strange. With the patch, I see each line of output to stderr being printed to the program's console gradually (that is very nice), but I don't see the similar stdout printouts until the very end of the program (which is how stdout is currently behaving on Windows). Why the difference?
(In reply to comment #4) > Very similar to bug 270369 in CDI. I've looked at the CDI solution which reads from GDB's error stream and prints to the GDB console. I'm curious to know why CDI chooses to print to the GDB console and not the process console? I couldn't quite find what GDB will print to its error stream, so are we worried that output that is not from the process could be printed there and that is why CDI goes to the GDB console?
Created attachment 196140 [details] CDI patch to use process console instead of GDB console Not being sure why CDI chooses to write stderr printouts to the GDB console, I tried it with the process console. This is the patch to do that. This is all so I can decide where DSF-GDB should print input received on GDB's stderr.
(In reply to comment #7) > I'm curious to know why CDI chooses to print to the GDB console and not the > process console? I couldn't quite find what GDB will print to its error > stream, so are we worried that output that is not from the process could be > printed there and that is why CDI goes to the GDB console? I don't understand why are you so confused. All GDB io streams go to the GDB console and the process streams to the process console, what's wrong with it?
(In reply to comment #7) > I'm curious to know why CDI chooses to print to the GDB console and not the > process console? I couldn't quite find what GDB will print to its error > stream, so are we worried that output that is not from the process could be > printed there and that is why CDI goes to the GDB console? The reason was I was seeing errors from GDB itself coming out GDB's stderr. Target output was being wrapped in MI and going correctly to the correct console. It may be that our GDB behaves differently to native linux gdb in which case there isn't a good reason...
(In reply to comment #9) > (In reply to comment #7) > > I'm curious to know why CDI chooses to print to the GDB console and not the > > process console? I couldn't quite find what GDB will print to its error > > stream, so are we worried that output that is not from the process could be > > printed there and that is why CDI goes to the GDB console? > > I don't understand why are you so confused. All GDB io streams go to the GDB > console and the process streams to the process console, what's wrong with it? On Windows, we cannot use a PTY, so I'm trying out CDI without the option to "Connect process input & output to a terminal". Currently cout << "Hello cout" << endl; this goes to the process console. cerr << "Hello cerr" << endl; this goes to the GDB console. That is because GDB's error stream is used to print the process stderr. I don't know what else GDB's error stream is used for, so, if it is only for the process' stderr, shouldn't we print this to the process console?
(In reply to comment #10) > The reason was I was seeing errors from GDB itself coming out GDB's stderr. > Target output was being wrapped in MI and going correctly to the correct > console. It may be that our GDB behaves differently to native linux gdb in > which case there isn't a good reason... If GDB uses its stderr for actual GDB errors, then I see the point, and I don't see how to differentiate between GDB error printouts and inferior error printouts. I don't know what GDB uses its stderr for. I'll have to ask.
(In reply to comment #9) > I don't understand why are you so confused. All GDB io streams go to the GDB > console and the process streams to the process console, what's wrong with it? Re-reading my first question, I can see why you didn't see my point, I didn't explain myself well at all.
(In reply to comment #12) > If GDB uses its stderr for actual GDB errors, then I see the point, and I don't > see how to differentiate between GDB error printouts and inferior error > printouts. Well I'm not sure whether GDB does do this. However any linked in simulators or target specific bits might just write to the error stream. There's a thread on target stderr vs. stdout: http://www.cygwin.com/ml/gdb-patches/2005-12/msg00011.html
Looks like this patch was committed: http://www.cygwin.com/ml/gdb-patches/2005-12/msg00095.html mi-interp.c has: ... /* Route target output through the MI. */ gdb_stdtarg = mi->targ; /* Route target error through the MI as well. */ gdb_stdtargerr = mi->targ; ... AFAICS this means that targets stdour and stderr will be wrapped in MI, which may be different from what happens for native debugging... http://www.cygwin.com/ml/gdb-patches/2005-12/msg00014.html
(In reply to comment #15) > Looks like this patch was committed: > http://www.cygwin.com/ml/gdb-patches/2005-12/msg00095.html > mi-interp.c has: > ... > /* Route target output through the MI. */ > gdb_stdtarg = mi->targ; > /* Route target error through the MI as well. */ > gdb_stdtargerr = mi->targ; > ... > > AFAICS this means that targets stdour and stderr will be wrapped in MI, which > may be different from what happens for native debugging... > > http://www.cygwin.com/ml/gdb-patches/2005-12/msg00014.html Right, so target errors will come out with @ in front (maybe not on linux, but we handle it also), and that will be on GDB's output stream. What goes on GDB stderr, I'm still trying to figure out
I was able to get GDB to print to stderr using CLI mode, as shown below. The 'display <use a type>' command will do it. > gdb.7.3 a.out GNU gdb (GDB) 7.2.90.20110420-cvs (gdb) l 1 struct str {}; 2 int main() { 3 str s; 4 return 0; 5 } (gdb) start Temporary breakpoint 1 at 0x804849a: file a.cc, line 4. Starting program: /home/lmckhou/testing/a.out Temporary breakpoint 1, main () at a.cc:4 4 return 0; (gdb) display str Disabling display 1 to avoid infinite recursion. 1: str = Attempt to use a type name as an expression I confirmed it was writing to stderr by redirecting GDB's stderr to a file like so: bash gdb.7.3 testing/a.out 2> tt And the string "Attempt to use a type name as an expression" got redirected. When using MI, 'gdb -i mi' and redirecting, that particular stderr printout comes out on stdout instead, with a & prefix. But a cerr or fprintf(stderr, from the inferior does come out on GDB's stderr. This makes me think that it is safe to print GDB's stderr to the inferior console.
(In reply to comment #17) > When using MI, 'gdb -i mi' and redirecting, that particular stderr printout > comes out on stdout instead, with a & prefix. But a cerr or fprintf(stderr, > from the inferior does come out on GDB's stderr. > > This makes me think that it is safe to print GDB's stderr to the inferior > console. This may be true for native GDB, but it's not true for target GDB. For target GDB, stdout and stderr for the target will always be in the MI. stderr of the GDB process will therefore only contain stuff that was fprintf(stderr, ...) from within the GDB process itself: i.e. a linked in simulator or target specific architecture bits. It may be true that GDB itself wraps its output in stderr, but it may not be the case that all the things that are linked with GDB wrap their stderr like this. Hence, for non-native targets, it makes sense to send GDB stderr to the gdb console and not to the target console.
(In reply to comment #18) > (In reply to comment #17) > > When using MI, 'gdb -i mi' and redirecting, that particular stderr printout > > comes out on stdout instead, with a & prefix. But a cerr or fprintf(stderr, > > from the inferior does come out on GDB's stderr. > > > > This makes me think that it is safe to print GDB's stderr to the inferior > > console. > > This may be true for native GDB, but it's not true for target GDB. For target > GDB, stdout and stderr for the target will always be in the MI. stderr of the > GDB process will therefore only contain stuff that was fprintf(stderr, ...) > from within the GDB process itself: i.e. a linked in simulator or target > specific architecture bits. > > It may be true that GDB itself wraps its output in stderr, but it may not be > the case that all the things that are linked with GDB wrap their stderr like > this. Hence, for non-native targets, it makes sense to send GDB stderr to the > gdb console and not to the target console. Makes sense. Considering that DSF-GDB currently ignores GDB's stderr altogether, and that CDI outputs to the GDB console, I think doing the same for DSF-GDB is good enough.
Created attachment 196157 [details] New thread to read GDB error stream This patch mimics the solution for CDI of bug 270369. It creates a new thread to read GDB's error stream and sends the string as an MI event for the AbstractCLIProcess to printout in the gdb console. I had to prefix the string with an '&' to indicate that it is an error printout to AbstractCLIProcess. By not using a PTY, I was able to confirm that inferior stderr printouts are now seen on the gdb console and we no longer have GDB hang when stderr gets full. Committed to HEAD.
Thanks for your help James. Can you review the fix?
Looks reasonable to me. (In reply to comment #20) > Considering that DSF-GDB currently ignores GDB's stderr altogether, and that > CDI outputs to the GDB console, I think doing the same for DSF-GDB is good > enough. I wonder if there'd a way to get this right in all cases. i.e. if (PTY || target {sim|...} ) send gdb stderr to GDB console else /* native debugging minus PTY */ send gdb stderr to target console I suspect most people using DSF/GDB will be on linux native, so it would make sense for stderr to go to the program console by default. If there was a way to configure where it went that might be an optimal solution?
*** cdt cvs genie on behalf of mkhouzam *** Bug 327617: Gdb hangs after user code writes to stderr multiple times [*] AbstractMIControl.java 1.17 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractMIControl.java?root=Tools_Project&r1=1.16&r2=1.17 [*] GDBBackend.java 1.27 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java?root=Tools_Project&r1=1.26&r2=1.27
(In reply to comment #22) > Looks reasonable to me. > > (In reply to comment #20) > > Considering that DSF-GDB currently ignores GDB's stderr altogether, and that > > CDI outputs to the GDB console, I think doing the same for DSF-GDB is good > > enough. > > I wonder if there'd a way to get this right in all cases. i.e. > if (PTY || target {sim|...} ) > send gdb stderr to GDB console > else /* native debugging minus PTY */ > send gdb stderr to target console > > I suspect most people using DSF/GDB will be on linux native, so it would make > sense for stderr to go to the program console by default. If there was a way to > configure where it went that might be an optimal solution? On linux native we _always_ use a PTY, and in that case, the inferior stderr goes to the PTY (i.e., the target console). So, this bug was really aimed at Windows users. But I'm all for a better solution for Windows, if we can figure something out. I'll leave it alone for now until someone requests it, or some solution is proposed.
*** Bug 344126 has been marked as a duplicate of this bug. ***
*** Bug 330751 has been marked as a duplicate of this bug. ***
Stderr and stdout should go to the same console on Windows, not stdout to the target console and stderr to the gdb console. My original patch accomplished this on Windows. This works properly on Linux.
I'm putting this back in the pool if someone has a solution that allows us to know which output of stderr should go to the process console and which should go to the gdb console.