LLDB failed to locate source when dwarf symbols are inside compile unit on Linux

Hi,

O ur company is using Buck(https://buckbuild.com/) to build internal service. Recently the build team made a change in buck to not merge dwarf symbols from each object file into final binary so debugger needs to read source/symbol table from compilation unit itself.
This seems to break the lldb in various aspect:

  1. Setting source line breakpoint in library files are not working
  2. Callstack did not show the source location well for library frame

I tried latest lldb which this bug still reproduces. Here is the logging for it:

(lldb) b TaoDataLayer.cpp:50
Target::AddBreakpoint (internal = no) => break_id = 6: file = ‘TaoDataLayer.cpp’, line = 50, exact_match = 0
error: Unable to set breakpoint for TaoDataLayer.cpp:50 at file address 0xffffffffffffffff

Breakpoint 6: no locations (pending).

WARNING: Unable to resolve breakpoint to any actual locations.

My debugging shows the Address::IsValid() returns false for line start symbol here because it’s file address is 0xffffffffffffffff:
https://github.com/llvm-mirror/lldb/blob/ceb5f6cd339a4bcd49666158578f883c1ec96663/source/Breakpoint/BreakpointResolver.cpp#L263

It seems that, after locating the symbol for the line_entry, the code below did not update sc.line_entry pointing to the original line_entry so it contains the uninitialized 0xffffffffffffffff value which will fail the isValid() check later:
https://github.com/llvm-mirror/lldb/blob/26fea9dbbeb3020791cdbc46fbf3cc9d7685d7fd/source/Symbol/CompileUnit.cpp#L375

I tried to fix this by doing “sc.line_entry = line_entry;” before both resolve_scope branches. This seems to fix the breakpoint but the callstack and source locator still can’t locate the source file correctly while hitting the breakpoint.

Questions:

  1. Is this a known issue? If so, is there any existing fix I can port?
  2. If not, does my investigation above sound reasonable? Any suggestion/direction for callstack and source locator part of fix?

Thanks
Jeffrey

Comments below.

Hey Greg, I just confirmed this with our build team. I seem to have misunderstood the location of debug symbol. It is actually not inside each individual object file but:

The debug info in dev mode sits in the .debug_* sections of the shared libraries (we don’t use debug fission).

One potential complicating factor is that we relativize the DW_AT_comp_dirattributes in the DWARF info, so that it’s almost always just a long reference to the current working directory (e.g. .///).

I do not know why this(symbol in shared library) would cause the bug though.

Jeffrey

In ELF files if there is a section named “.gnu_debuglink” it will contain a path to the external debug file. Dump this section and see what it contains. This section contains a null terminated C string as the path followed by a 4 byte aligned 32 bit integer which is a file CRC. Check to see the path is relative.

I am guessing this is your problem.

Greg

Hi Jeffrey,

For the source code locating issue based on your info my guess is that LLDB doesn’t able to resolve the relative file name path specified in your symbol files to the absolute path required to load the file from disk. Can you try running "target modules dump line-table " where the file name is just the name of the file without any path? If the problem is what I am guessing then you should see an output like this (note the relative path).

(lldb) target modules dump line-table s.cpp
Line table for ./foo/s.cpp in `a.out
0x0000000000400a0d: ./foo/s.cpp:3
0x0000000000400a1a: ./foo/s.cpp:4
0x0000000000400a58: ./foo/s.cpp:4
0x0000000000400a64: ./foo/s.cpp:5
0x0000000000400a93: ./foo/s.cpp:6
0x0000000000400a9e: ./foo/s.cpp:6

The above problem can be worked around either by running LLDB with a current working directory where the file path displayed by “target modules dump line-table” is relative to or setting up a directory remapping for that path using "settings set target.source-map ./ ".

Tamas