Bug 408389 - Source lookup gets confused by invalid fullname returned by GDB
Summary: Source lookup gets confused by invalid fullname returned by GDB
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-debug-dsf-gdb (show other bugs)
Version: 8.2   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on: 472765
Blocks:
  Show dependency tree
 
Reported: 2013-05-18 11:48 EDT by Sergey Prigogin CLA
Modified: 2020-09-04 15:19 EDT (History)
4 users (show)

See Also:


Attachments
example script demoing PWD issue (1.34 KB, text/plain)
2016-04-12 05:58 EDT, Jonah Graham CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey Prigogin CLA 2013-05-18 11:48:48 EDT
Some build systems set DW_AT_comp_dir in DWARF to "/proc/self/cwd", which simply means the current working directory. This value propagates to fullname returned by gdb, for example:
412,903 21-break-insert --thread-group i1 -f mydir/myfile.cc:82
412,986 21^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000000000040ca8f",func="MyTest_Test::TestBody()",file="mydir/myfile.cc",fullname="/proc/self/cwd/mydir/myfile.cc",line="82",thread-groups=["i1"],times="0",original-location="mydir/myfile.cc:82"}

If the debugger runs in a directory different from the compilation directory, the fullname path becomes invalid, and CDT is not able to find the source file when the breakpoint is hit.
Comment 1 Sergey Prigogin CLA 2013-05-18 13:56:35 EDT
http://sourceware.org/ml/gdb-patches/2012-12/msg00811.html describes the GDB change called "Print MI fullname even for non-existing files". It looks like this change is to blame for the source lookup breakage described in comment #0. On 20 Dec 2012 Marc Khouzam wrote about this change: "So I find the patch in fact an improvement even for Eclipse." It seems that this conclusion should be reconsidered.

One possible solution is to validate fullname path immediately upon receiving it from GDB and discard it if the file it points to doesn't exist.
Comment 2 Sergey Prigogin CLA 2013-05-22 13:05:07 EDT
A proposed fix is in Gerrit at https://git.eclipse.org/r/#/c/12964/.
Comment 3 Nobody - feel free to take it CLA 2013-05-22 13:35:24 EDT
(In reply to comment #2)
> A proposed fix is in Gerrit at https://git.eclipse.org/r/#/c/12964/.

Sergey,

Would your patch work if the executable is built somewhere else? With the current code we can still debug it using the path mapping mechanism.
Comment 4 Sergey Prigogin CLA 2013-05-22 13:43:46 EDT
(In reply to comment #3)
> Would your patch work if the executable is built somewhere else? With the
> current code we can still debug it using the path mapping mechanism.

The patch does work if the source lookup is configured properly since the files are found by their relative paths.

Perhaps it would be better to apply path mapping and check for file existence at the same time. Could you please point me to the path mapping code. Thanks.
Comment 5 Nobody - feel free to take it CLA 2013-05-22 14:03:16 EDT
(In reply to comment #4)
> (In reply to comment #3)
> > Would your patch work if the executable is built somewhere else? With the
> > current code we can still debug it using the path mapping mechanism.
> 
> The patch does work if the source lookup is configured properly since the
> files are found by their relative paths.
> 
> Perhaps it would be better to apply path mapping and check for file
> existence at the same time. Could you please point me to the path mapping
> code. Thanks.

Not sure I understand what you mean. There is no way to specify a file that doesn't exist as local file using the path mapping mechanism. The UI doesn't allow it. 
The source containers are:
org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer
org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer
Comment 6 Sergey Prigogin CLA 2013-05-22 14:09:24 EDT
(In reply to comment #5)
> Not sure I understand what you mean. There is no way to specify a file that
> doesn't exist as local file using the path mapping mechanism. The UI doesn't
> allow it. 
> The source containers are:
> org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer
> org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer

I meant that ideally the check for existence should be done after an attempt to map the file. If that attempt is unsuccessful and the file doesn't exist, the absolute path should be ignored.
Comment 7 Nobody - feel free to take it CLA 2013-05-22 15:04:50 EDT
(In reply to comment #6)
> (In reply to comment #5)
> > Not sure I understand what you mean. There is no way to specify a file that
> > doesn't exist as local file using the path mapping mechanism. The UI doesn't
> > allow it. 
> > The source containers are:
> > org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer
> > org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer
> 
> I meant that ideally the check for existence should be done after an attempt
> to map the file. If that attempt is unsuccessful and the file doesn't exist,
> the absolute path should be ignored.

What if we just add a special global path mapping for your case? With proposed changes the source lookup would often find a wrong file.
Comment 8 Sergey Prigogin CLA 2013-05-22 15:15:26 EDT
(In reply to comment #7)
> What if we just add a special global path mapping for your case? With
> proposed changes the source lookup would often find a wrong file.

A global path mapping would not work since different sources are compiled in different compilation directories. These compilation directories are all represented by /proc/self/cwd in fullname. Relative paths do work because they are resolved against source lookup that is aware of all compilation directories.
Comment 9 Nobody - feel free to take it CLA 2013-05-22 15:38:59 EDT
(In reply to comment #8)
> (In reply to comment #7)
> > What if we just add a special global path mapping for your case? With
> > proposed changes the source lookup would often find a wrong file.
> 
> A global path mapping would not work since different sources are compiled in
> different compilation directories. These compilation directories are all
> represented by /proc/self/cwd in fullname. Relative paths do work because
> they are resolved against source lookup that is aware of all compilation
> directories.

Yes, I realized it after reading the description once again. 
I see two options:
1. Using the source lookup twice, first time with the full path and then with the relative path.
2. Strip '/proc/self/cwd' before passing the file name to the source lookup.
What do you think?
Comment 10 Sergey Prigogin CLA 2013-05-22 16:23:33 EDT
(In reply to comment #9)
> (In reply to comment #8)
> > (In reply to comment #7)
> > > What if we just add a special global path mapping for your case? With
> > > proposed changes the source lookup would often find a wrong file.
> > 
> > A global path mapping would not work since different sources are compiled in
> > different compilation directories. These compilation directories are all
> > represented by /proc/self/cwd in fullname. Relative paths do work because
> > they are resolved against source lookup that is aware of all compilation
> > directories.
> 
> Yes, I realized it after reading the description once again. 
> I see two options:
> 1. Using the source lookup twice, first time with the full path and then
> with the relative path.
> 2. Strip '/proc/self/cwd' before passing the file name to the source lookup.
> What do you think?

Option 1 looks like a more general and robust solution. I'm not sure how to fit it into existing code structure though.
Comment 11 Nobody - feel free to take it CLA 2013-05-22 16:40:54 EDT
(In reply to comment #10)
> (In reply to comment #9)
> > (In reply to comment #8)
> > > (In reply to comment #7)
> > > > What if we just add a special global path mapping for your case? With
> > > > proposed changes the source lookup would often find a wrong file.
> > > 
> > > A global path mapping would not work since different sources are compiled in
> > > different compilation directories. These compilation directories are all
> > > represented by /proc/self/cwd in fullname. Relative paths do work because
> > > they are resolved against source lookup that is aware of all compilation
> > > directories.
> > 
> > Yes, I realized it after reading the description once again. 
> > I see two options:
> > 1. Using the source lookup twice, first time with the full path and then
> > with the relative path.
> > 2. Strip '/proc/self/cwd' before passing the file name to the source lookup.
> > What do you think?
> 
> Option 1 looks like a more general and robust solution. I'm not sure how to
> fit it into existing code structure though.

I think using a new service that extends CSourceLookup for affected GDB versions would work. We just need to override ISourceLookup.getSource().
BTW, can you set a breakpoint with those full paths?
Comment 12 Nobody - feel free to take it CLA 2013-05-22 16:56:14 EDT
(In reply to comment #11)
> (In reply to comment #10)
> > (In reply to comment #9)
> > > (In reply to comment #8)
> > > > (In reply to comment #7)
> > > > > What if we just add a special global path mapping for your case? With
> > > > > proposed changes the source lookup would often find a wrong file.
> > > > 
> > > > A global path mapping would not work since different sources are compiled in
> > > > different compilation directories. These compilation directories are all
> > > > represented by /proc/self/cwd in fullname. Relative paths do work because
> > > > they are resolved against source lookup that is aware of all compilation
> > > > directories.
> > > 
> > > Yes, I realized it after reading the description once again. 
> > > I see two options:
> > > 1. Using the source lookup twice, first time with the full path and then
> > > with the relative path.
> > > 2. Strip '/proc/self/cwd' before passing the file name to the source lookup.
> > > What do you think?
> > 
> > Option 1 looks like a more general and robust solution. I'm not sure how to
> > fit it into existing code structure though.
> 
> I think using a new service that extends CSourceLookup for affected GDB
> versions would work. We just need to override ISourceLookup.getSource().

Sorry, I am too tired. Overriding ISourceLookup.getSource() doesn't work. We need two paths (absolute and relative) but it only accepts one.
I think the second option is easier to implement.

> BTW, can you set a breakpoint with those full paths?
Comment 13 Sergey Prigogin CLA 2013-05-22 18:48:24 EDT
I've implemented a local solution to this problem, so we can leave the current behavior in place as long as nobody else is suffering from it.
Comment 14 Jonah Graham CLA 2015-12-28 06:05:42 EST
I believe this bug is fixed by Bug 472765. With the changes in Bug 472765 the path mapping maps /proc/self/cwd/mydir to /the/real/path/to/mydir and does a "set substitute-path /proc/self/cwd/mydir /the/real/path/to/mydir", after the substitution is issued to GDB, further breakpoints can be inserted on /the/real/path/to/mydir/myfile.cc and GDB will report fullname as /the/real/path/to/mydir/myfile.cc too.

However, I don't have access to a GCC that behaves this way so I cannot test.
Comment 15 Jonah Graham CLA 2016-04-12 05:56:16 EDT
(In reply to Jonah Graham from comment #14)
> I believe this bug is fixed by Bug 472765. With the changes in Bug 472765
> the path mapping maps /proc/self/cwd/mydir to /the/real/path/to/mydir and
> does a "set substitute-path /proc/self/cwd/mydir /the/real/path/to/mydir",
> after the substitution is issued to GDB, further breakpoints can be inserted
> on /the/real/path/to/mydir/myfile.cc and GDB will report fullname as
> /the/real/path/to/mydir/myfile.cc too.
> 
> However, I don't have access to a GCC that behaves this way so I cannot test.

While this bug is significantly improved by Bug 472765's fixes, there are still some cases that CDT does not handle because GDB does not handle them. Namely, in the case that /proc/self/cwd actually refers to two different locations GDB cannot resolve it.

Here is an example of how someone sets DW_AT_comp_dir in DWARF to "/proc/self/cwd". It is about llvm but the principle is the same. http://lists.llvm.org/pipermail/cfe-dev/2011-October/018068.html

That said, the long term fix needs to be on the GDB side, i.e. there needs to be a way to configure GDB to work in this case with no CDT involved. If there is a delay in GDB providing a fix, then CDT can have a workaround until the proper fix is available.
Comment 16 Jonah Graham CLA 2016-04-12 05:58:13 EDT
Created attachment 260886 [details]
example script demoing PWD issue

This script shows how to create an executable with DW_AT_comp_dir that become unresolvable by GDB.