API for loading debug symbols

Hi lldb-dev,

I’m trying to write some tooling to help with debugging complex builds on Mac. The libraries all have debugging info separated into .dSYM/ directories. Due to some complexities in our build system, the .dSYM directories with the debugging info have completely different base paths than the actual library being loaded, and there are multiple different base paths in use for the debug symbols.

For example,

Libraries without debugging symbols:




Corresponding debugging symbols:




I’m looking for an LLDB API (preferably part of the python API) that I can use to load the debug symbols for these libraries when the libraries in my workspace are loaded.

I’ve tried using ‘lldb.target.AddModule()’ to load an additional module after the original module is loaded (using the 4-arg version which allows a separate symfile to be specified). After doing this though when I call GetNumCompileUnits() on the new module, it still reports 0. I also have no idea if this module I just added will be used by LLDB instead of the one it originally loaded without debug symbols.

I’ve looked at locate_module_and_debug_symbols() in lldb.utils.symbolication.Image (as mentioned here: http://lldb.llvm.org/symbolication.html). Presumably I could create a custom class which overrides this method, however I didn’t see any way to tell LLDB to use this custom method when loading modules.

I’ve also looked at the DBGShellCommands described here: http://lldb.llvm.org/symbols.html. This has several drawbacks, including:

  1. performance implications (~1000 modules are loaded, constantly in flux so the home-directory-based symlink cache isn’t practical)

  2. no runtime configurability (there doesn’t appear to be a way to specify the script as an lldb startup argument, so I need to use the macos ‘defaults’ tool, and install it in the user’s home directory, which means we can’t have different scripts in use when debugging multiple different workspaces at the same time).

  3. no equivalent capability when using lldb on Linux

I’ve solved this problem on GDB using the Objfile.add_separate_debug_file() method in their python API: https://sourceware.org/gdb/onlinedocs/gdb/Objfiles-In-Python.html

I’ve been scratching my head for a couple of days now. Does this seem possible, and are there any suggestions for how to proceed?



Yes: use the "target symbols add" to do thing manually:

(lldb) target symbols add --shlib-name /path/to/my/workspace/bin/maci64/libA.dylib /archive/builds/1234/bin/maci64/libA.dylib.dSYM/Contents/Resources/DWARF/libA.dylib

But, if you are on MacOSX, Spotlight should be locating these files for us and should allow us to find them without the need to do anything. You can see if spotlight has indexed a dSYM by doing:

% mdls a.out.dSYM
com_apple_xcode_dsym_paths = (
com_apple_xcode_dsym_uuids = (

If you see "com_apple_xcode_dsym_paths" and "com_apple_xcode_dsym_uuids" keys, you should be good to go and LLDB should just find the dSYM files for you. Spotlight does have a bunch of rules where it doesn't parse in certain directories so if you don't see the "com_apple_xcode_dsym_XXXX" keys, then it might be because of a folder name (the "builds" might stop Spotlight from indexing the symbols), but unfortunately Spotlight doesn't say where it will and won't parse. One notable issues is it doesn't parse in temporary folders ("/tmp" or "/var/folders/cf/k0g8rm6d2zq44qzlnw4pbz4w0007k2/T").

If you do see the "com_apple_xcode_dsym_XXXX" keys in your mdls output, then you can see if spotlight will find your dSYM file by using "mdfind":

% mdfind C04CC660-24AE-3810-87DF-2CA334E462DD

If you see the path to your dSYM file, then LLDB should find the symbols. If you disable spotlight, then all bets are off of course.

Greg Clayton

Yes: use the "target symbols add" to do thing manually:

(lldb) target symbols add
--shlib-name /path/to/my/workspace/bin/maci64/libA.dylib /archive/builds/1234/bin/maci64/libA.dylib.dSYM/Contents/Resources/DWARF/libA.dylib

Thanks. I tested this interactively, and it seems to work, although I
needed to modify the command:

(lldb) target symbols add /archive/builds/1234/bin/maci64/libA.dylib.dSYM/Contents/Resources/DWARF/libA.dylib

The '--shlib-name' option doesn't seem to be recognized, but '--shlib'
is. However it produced the following error:

(lldb) target symbols add --shlib /path/to/my/workspace/bin/maci64/libA.dylib /archive/builds/1234/bin/maci64/libA.dylib.dSYM/Contents/Resources/DWARF/libA.dylib
error: specify either one or more paths to symbol files or using the --file option without arguments

It looks like the 'target symbols add' without the --shlib does work
correctly, as I can see the compilation unit and source code when I hit
breakpoints in the library. I'm guessing it works by matching the UUID
of the new library with the UUID of the existing library.

But, if you are on MacOSX, Spotlight should be locating these files
for us and should allow us to find them without the need to do

Spotlight is not configured to index these paths. They are
autofs-mounted NFS volumes, so they don't appear by default. The
archived builds are huge and there are lots of them, so its just
not practical to index them on each system. That certainly would be
convenient if it worked though.


That makes perfect sense. So will this be enough to get you going them?

I think so. I am curious what the correct way would be to use
the '--shlib' option would be since I couldn't get it to work.

I'm going to try creating a python script which registers for the
lldb.SBTarget.eBroadcastBitModulesLoaded event, and when a new
module is loaded that doesn't have any compilation units,
it will then call the 'target symbols add' command to add the
additional dylib file.

I'll post back if I'm unable to get it to work.