Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 232415

Summary: [breakpoints] Can't set breakpoints in Windows
Product: [Tools] CDT Reporter: Francois Chouinard <fchouinard>
Component: cdt-debug-dsf-gdbAssignee: Pawel Piech <pawel.1.piech>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: cdtdoug, dd.general-inbox, pawel.1.piech
Version: 0 DD 1.0   
Target Milestone: DD 1.0   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
Quick&Dirty (Temporary) Fix
none
MinGW specific patch cdtdoug: iplog-

Description Francois Chouinard CLA 2008-05-15 17:18:25 EDT
When trying to set a breakpoint in Windows, GDB complains that it can't find the source file and the breakpoint is not inserted.

For example:

-break-insert C:\\<workspace path>\\HelloWorld\\src\\HelloWorld.c:15

The MI error message is something like "Can't find C:\\...\\HelloWorld.c in loaded symbols".

Surprisingly, the following works fine:

-break-insert C:\\<workspace path>\\HelloWorld\\Debug\\..\\src\\HelloWorld.c:15

The problem seems to be Windows specific and I could reproduce with GDB 6.5, 6.6 and 6.8. However, this works fine in CDI.

Looking at CDI, we notice that they specify a source directory path and then they set the breakpoint in the form HelloWorld.c:<linenumber>. In that case, GDB has no problem identifying and inserting corresponding breakpoint in the binary file (essentially finding the source file name in the binary's symbol table).

In DSF (where we try harder :-), when inserting a breakpoint, we provide the full debugger path to the source file and a line number (or function name). This is what fails in Windows. At first glance, it looks like the SourceLookup function is not working properly in that case.
Comment 1 Francois Chouinard CLA 2008-05-15 18:22:49 EDT
Created attachment 100567 [details]
Quick&Dirty (Temporary) Fix

The attached patch is a quick hack to get the Windows breakpoints working. It works fine for Windows and Linux. I haven't tried it on other platforms.

The longer term solution is probably to fix the SourceLookup service.

Randy, please let me know if it fixes your problem.

Best Regards,
/fc
Comment 2 Francois Chouinard CLA 2008-05-22 15:38:08 EDT
Created attachment 101604 [details]
MinGW specific patch

Typically, when creating a C/C++ project in Eclipse CDT, the source files are stored in the src/ directory while the executable is stored in either Debug/ or Release/ depending on the build configuration. When generating a debug executable (-g), the list of source files, including the header files, is also stored in the binary file. Internally, the source file paths seem to be stored as relative to the executable location (at compile time), e.g. "../src/sourcefile.c". You can have a look at the source files with the GDB "info sources" command. Apparently, this is the path given to GCC when building the executable.

When executing, GDB seems to use a couple of path variables: $cdir (compilation directory) and $cwd (current working directory) to resolve the breakpoint location. When asked to insert the breakpoint from the GUI, MIBreakpointsManager provides a full, canonical path to the back-end. GDB then tries to match this path with the binary symbols table. According to the documentation, GDB is supposed to be very flexible when trying to match a source file name with one of its symbols. Although it works very well with Unix-like paths (Linux, Cygwin), it is not so great for Windows paths (MinGW).

For example, it rejects:
- C:/Workspaces/HelloWorld/src/HelloWorld.c:xx ("No source file named ...")

but accepts:
- HelloWorld.c:xx.
- ../src/HelloWorld.c:xx.
- C:/Workspaces/HelloWorld/Debug/../src/HelloWorld.c:xx

At first glance, this is a GDB bug (when using Windows paths) which accepts either the plain filename or the path relative to the compilation/execution directory.

Circumventing this problem is not so obvious:

[1] When determining the debugger path to the source file, there is no CBreakpoint attributes that can be used to determine a path relative to $cdir/$cwd. When a CBreakpoint is created, a source handle is provided to the CBreakpoint constructor. This source handle is typically the result of a call to CDebugUIUtils.getEditorFilePath() which returns the canonical workspace file name for the underlying OS, not a path relative to the executable.

[2] It would also be shaky to make assumptions about the compilation directory and try to derive a relative path form it: (a) the compilation directory could be anywhere, (b) there is no guarantee that a relative "canonical" path is the one that was provided to GCC in the first place.

[3] The only sure way to determine the actual source file paths is probably to ask GDB for that list and then to map the files to the workspace resources :-(

All this seems to be an overkill just to circumvent a GDB bug that shows with MinGW.

As a temporary fix, I suggest that we just provide the filename (i.e. strip the path) in the debuggerPath when dealing with native windows paths. We loose scalability but at least breakpoints can be set.

Patch attached.

Best Regards,
/fc
Comment 3 Francois Chouinard CLA 2008-05-22 15:40:12 EDT
Pawel,

Unless you have a very smart and non-API-breaking solution for this one, I suggest that the patch could be checked in.

BR,
/fc
Comment 4 Pawel Piech CLA 2008-05-22 15:57:10 EDT
(In reply to comment #3)
> Unless you have a very smart and non-API-breaking solution for this one, I
> suggest that the patch could be checked in.
+1 from Pawel
Comment 5 Francois Chouinard CLA 2008-05-22 16:05:31 EDT
Patch was committed.
Comment 6 Pawel Piech CLA 2008-06-17 17:46:54 EDT
Verified.
Comment 7 Pawel Piech CLA 2008-08-13 13:04:41 EDT
Closing out 1.0 bugs.