Please note when trying to replicate this, you need to dig in a bit closely- there's a bit of luck that can occur here resulting in it working; this is part of the reason. The git pkg uses hardlinks for most of it's commands; git, git-mailinfo, etc, all being a hardlink to the same file. Portage is smart enough to recognize that hardlinks are in play here, and to only mangle the actual inode once, doing the following for each unique inode: objcopy --only-keep-debug ${D}/usr/bin/git ${D}/usr/lib/debug/usr/bin/git.debug strip --strip-debug ${D}/usr/bin/git objcopy --add-gnu-debuglink=${D}/usr/lib/debug/usr/bin/git.debug ${D}/usr/bin/git The problem here is that binutils implementation of --add-gnu-debuglink records a record of the basename of the given debug file (look in bfd_create_gnu_debuglink-section)- not the absolute path at the time of invocation. Literally, /usr/bin/git gets 'git.debug' recorded. This is where hardlinks screw the pooch. If we're lucky for that case, 'git.debug' is the recorded debuglink. If we're not, one of the libexec/git-core binaries is what's recorded, something like 'git-whatchanged'. Because the record is just the basename, gdb has to look relative- so for example, it would check /usr/bin/git-mailinfo.debug /usr/bin/.debug/git-mailinfo.debug /usr/lib/debug/usr/bin/git-mailinfo.debug Etc. Which if the first node processed results in a common name like 'git.debug', mostly works by luck. If it's something like 'git-whatchanged.debug', that however doesn't work. A way to verify this behaviour is a mixture of the following commands: readelf -p .gnu_debuglink /usr/bin/git # pull the recorded string gdb --args /usr/bin/git # note the failure to find debug symbols gdb --args /usr/libexec/git-core/git # note that it succeeded, because it could find 'git-whatchanged.debug' (or whatever it was named) relative to that offset pathway). When testing this, you may have to do an objcopy --add-gnu-debuglink invocation to switch the inode's recorded .gnu_debuglink to something like git-whatchanged.debug. Unfortunately this is a bit nasty- our options are- 1) hardlink breaking as needed if the reference would point outside the relative directory, and add a new gnu-debuglink. The code to do this is ugly from the PM standpoint. 2) modify binutils to record absolute pathways for .gnu_debuglink; this is slightly more complex then it sounds, would require adding another option to record the final installed location of the debugfile; keep in mind binutils needs access to the debugfile during adding the record for accessing crcs. Thus we'd have to give it the current path to the debugfile, /and/ tell it "the debugfile will live over there- thus record that pathway". 3) find some other tool that we can invoke after the --add-gnu-debuglink to inject in the final on disk abspath. Not sure how feasible that is, including making sure the crc's don't get screwed up. Thoughts? This isn't binutils version specific, but 2.22* still holds the offending code, and any 2.1/2.2 portage version will do this (this pathway hasn't changed in a long while, aside from the recent compressdebug addition).
*** Bug 406159 has been marked as a duplicate of this bug. ***
@Brian: (in case you still remember :), What actually triggers this problem? I.e., what determines *which* name is recorded in the inode? [I checked and the objcopy behaviour hasn't changed in the meantime.]
(In reply to Andreas K. Hüttel from comment #2) > @Brian: (in case you still remember :), > > What actually triggers this problem? I.e., what determines *which* name is > recorded in the inode? > > [I checked and the objcopy behaviour hasn't changed in the meantime.]