Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 356085 - GDB MI parser in CDT/CDI is broken on Windows
Summary: GDB MI parser in CDT/CDI is broken on Windows
Status: RESOLVED WONTFIX
Alias: None
Product: CDT
Classification: Tools
Component: cdt-debug-cdi-gdb (show other bugs)
Version: 8.0   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Elena Laskavaia CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-29 10:26 EDT by Stefan Bylund CLA
Modified: 2017-10-23 13:39 EDT (History)
3 users (show)

See Also:


Attachments
Simple test program for exemplifying the bug (174 bytes, text/plain)
2011-08-29 10:26 EDT, Stefan Bylund CLA
no flags Details
Patch for org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/RxThread.java (2.48 KB, patch)
2011-08-29 10:28 EDT, Stefan Bylund CLA
no flags Details | Diff
Patch for org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIParser.java (3.49 KB, patch)
2011-08-29 10:29 EDT, Stefan Bylund CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Bylund CLA 2011-08-29 10:26:06 EDT
Build Identifier: Eclipse 3.7.0 (Build id: I20110613-1736), CDT 8.0.0 (Build id: 201106081058)

Problem Description
-------------------

I will start with some background information. Starting from CDT 7, a Windows program that is debugged with CDT and GDB will not get a native Windows console but will instead be integrated with the Eclipse console. Due to this change, CDT 7 and 8 does not support source code debugging with GDB of Windows programs that prints non-newline-terminated strings on stdout. This bug appears both in CDI's and DSF's GDB support but this bug report focuses on CDI (see bug 356082 for the corresponding DSF bug report and fix).

This is not a problem on operating systems that support pseudo terminals (like Linux but not Windows). On Linux, CDT redirects the debugged program's output to a different pseudo terminal (TTY). That lets CDT unambiguously differentiate between GDB's output and the debugged program's output. Windows doesn't have TTYs, so the output from GDB and the debugged program can be interleaved if the debugged program prints non-newline-terminated strings on stdout at the same time as an event occurs in GDB (e.g. the end of a single-step over the offending printf() line in the debugged program). The problem is that the current GDB MI parser fails to recognize this fact and consequently does not react to the MI output that signals the end of the single-step operation, which makes the debug session appear as it has hanged.

Solution
--------

Since Windows doesn't have pseudo terminals, the GDB MI parser can only make a best effort of differentiating between the output from GDB and the debugged program. Currently, this differentiating is much too weak, as is demonstrated by the the example above.

I have only been able to get interleaved output from GDB and its debugged program when I single-step over non-newline-terminated output on stdout from the debugged program. In those cases, the output from the debugged program always precedes the output from GDB, like this:

<debugged-program-output><gdb-mi-output>\n

So, one straighforward way to make the GDB MI parser much more robust on Windows is to let its main loop (which reads each line of output from GDB and parses it) analyze the line of output from GDB and try to split it up in one debugged program part and in one GDB part (if they occur on the same line) and then send those two separate lines of output to the GDB MI parsing method. The code for splitting up the output from GDB uses a regular expression of the GDB MI output grammar.

A patch, relative to CDT 8.0.0, for the GDB MI parser in CDI is provided. When making the fixes for both CDI and DSF, I noticed that the GBD MI parser in DSF, which was based on the GDB MI parser in CDI, contains improved parsing of the 'token' part of the GDB MI output. I have added those improvements back to the GDB MI parser in CDI since they are needed to make this fix robust in the CDI case as well.

The classes org.eclipse.cdt.debug.mi.core.RxThread and org.eclipse.cdt.debug.mi.core.output.MIParser in the org.eclipse.cdt.debug.mi.core plugin have been updated.


Reproducible: Always

Steps to Reproduce:
1. Make sure that you have a MinGW or Cygwin GCC/GDB installed.
2. Create an empty C project for executables and choose the toolchain MinGW GCC or Cygwin GCC.
3. Add the attached file test.c to the project and build it.
4. Create a "C/C++ Application" debug launch configuration and choose "Standard Create Process Launcher" as launcher.
5. Launch the debugger; you should now be in the main() function in test.c.
6. Try to step over the printf() and fflush() lines; one of them will fail, typically the fflush() line!
7. The debug session is now hanged...
Comment 1 Stefan Bylund CLA 2011-08-29 10:26:52 EDT
Created attachment 202325 [details]
Simple test program for exemplifying the bug
Comment 2 Stefan Bylund CLA 2011-08-29 10:28:19 EDT
Created attachment 202326 [details]
Patch for org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/RxThread.java
Comment 3 Stefan Bylund CLA 2011-08-29 10:29:51 EDT
Created attachment 202327 [details]
Patch for org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIParser.java
Comment 4 Elena Laskavaia CLA 2011-08-30 20:49:07 EDT
What is the intend of changes in MIParser? Looks like bunch of refactoring,
the only functionality change would be that in case of unrecognized line it would
print id + buffer instead of just buffer, why just not to change 1 line there?
Comment 5 Stefan Bylund CLA 2011-08-31 02:51:04 EDT
The original version of the MIParser in CDI assumes that any starting digits in the GDB MI output is part of a GDB token (called 'id' in the MiParser). If the non-newline-terminated output from the debugged program contains digits at its start, those digits will be consumed by the MIParser and removed from the output of the debugged program. For example, if the output from the debugged program is "10 Hello World", then the string that is actually printed in the console is " Hello World", i.e. "10" has been 'stolen' by the MIParser.

I discovered this behavior when I debugged this problem and developed the patches for both CDI and DSF. In my test program I had multiple non-newline-terminated printf() statements and to separate them more easily I had prepended each output string with a sequence number. This made me notice that the numbers disappeared in the CDI case while they remained in the DSF case. I then compared the MI parsers in DSF and CDI and noticed that this issue had been fixed in DSF. Since the MI parser in DSF is obviously based on the CDI version, I thought it was a good idea to back port this improvement to CDI as well.

The changes in MIParser.java are not crucial for this patch. The important changes are in RxThread.java. If you disapprove with the changes in MIParser.java, I can live with that :-)
Comment 6 Stefan Bylund CLA 2011-09-07 05:09:51 EDT
Is there any chance of having this fix included in CDT 8.0.1? Can I do anything to facilitate that?
Comment 7 Jonah Graham CLA 2017-10-23 13:39:23 EDT
(this is part of a batch change)

The CDI debug implementation has been removed in CDT 9.0. Please see bug 484900 and the entry on the New and Noteworthy page https://wiki.eclipse.org/CDT/User/NewIn90#API_modifications