Directories to search for separate debugging information

Hi lldb-dev,

There is a “debug-file-directory” concept in gdb to use for debug information in separate files and I am wondering if you can suggest to me an equivalent/related concept in lldb.
That is, in gdb, one can use the command 'set debug-file-directory to specify an hierarchy of directories in which to search for debugging information.
Is there such a concept in lldb? If you guys are not the right people to ask, perhaps you can point me in the right direction. If such a command is documented I must have missed it.

This is the gdb info:

(gdb) help set debug-file-directory
Set the directory where separate debug symbols are searched for.
Separate debug symbols are first searched for in the same
directory as the binary, then in the `.debug’ subdirectory,
and lastly at the path of the directory of the binary with
the global debug-file directory prepended.

Thanks,
Sara

Is this for MacOSX debugging, or another system?

We don't currently have this in LLDB, except on MacOSX, LLDB uses DebugSymbols.framework to locate the dSYM files for your executables. This has many ways to track down dSYM files, including spotlight, explicit paths like ~/Library/Symbols, and many other ways. So if you are on a Mac, just make sure the dSYM file is somewhere that spotlight can see it, and we will find it for you without any need for further work.

Greg Clayton

You can enable the shell script using:

% defaults write com.apple.DebugSymbols DBGShellCommands /path/to/shellscript

Your shell script will be invoked with a UUID string value like "23516BE4-29BE-350C-91C9-F36E7999F0F1". The shell script can respond with a plist in the following format:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>23516BE4-29BE-350C-91C9-F36E7999F0F1</key>
  <dict>
    <key>DBGArchitecture</key>
    <string>i386</string>
    <key>DBGBuildSourcePath</key>
    <string>/path/to/build/sources</string>
    <key>DBGSourcePath</key>
    <string>/path/to/actual/sources</string>
    <key>DBGDSYMPath</key>
    <string>/path/to/foo.dSYM/Contents/Resources/DWARF/foo</string>
    <key>DBGSymbolRichExecutable</key>
    <string>/path/to/unstripped/exectuable</string>
  </dict>
  <key>A40597AA-5529-3337-8C09-D8A014EB1578</key>
  <dict>
    <key>DBGArchitecture</key>
    <string>x86_64</string>
    .....
  </dict>
</dict>
</plist>

Note that this file contained two architectures so it has two UUID key/value pairs.

Since dSYM files are bundles, you can also place UUID info plists files inside your dSYM bundles:

/path/to/foo.dSYM/Contents/Resources/23516BE4-29BE-350C-91C9-F36E7999F0F1.plist
/path/to/foo.dSYM/Contents/Resources/A40597AA-5529-3337-8C09-D8A014EB1578.plist

% cat /path/to/foo.dSYM/Contents/Resources/23516BE4-29BE-350C-91C9-F36E7999F0F1.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>DBGArchitecture</key>
    <string>i386</string>
    <key>DBGBuildSourcePath</key>
    <string>/path/to/build/sources</string>
    <key>DBGSourcePath</key>
    <string>/path/to/actual/sources</string>
    <key>DBGDSYMPath</key>
    <string>/path/to/foo.dSYM/Contents/Resources/DWARF/foo</string>
    <key>DBGSymbolRichExecutable</key>
    <string>/path/to/unstripped/exectuable</string>
</dict>
</plist>

These have the exact same content as the above shell script output, so it makes making the results of your shell script very easy to create by combining two plists into a single one where you take the UUID and use it a string key, and the value is the contents of the plist.

Then LLDB will always know that your debug info contains source paths like "/path/to/build/sources" and it will remap them to "/path/to/actual/sources" by parsing these plist files in the dSYM bundle. This is something your build system can take care of.

We have a shell script at Apple and it goes a step further and caches these files locally in a known location so the next query for the dSYM file will be able to use the cached version. To do this, we "file map" the UUID values by chopping up the UUID into 4 character chunks and making the last value a symlink to the locally cached dSYM file:

~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1
~/Library/SymbolCache/dsyms/uuids/A405/97AA/5529/3337/8C09/D8A014EB1578

The last entries in these file mapped directories are symlinks to the actual dsym mach file in the dsym bundle:

ls -lAF ~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1

~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1@ -> ../../../../../../dsyms/foo.dSYM/Contents/Resources/DWARF/foo

Then you can also tell DebugSymbols to check this "file mapped" cache first using:

% defaults write com.apple.DebugSymbols DBGFileMappedPaths ~/Library/SymbolCache/dsyms/uuids

So if you enable both:

% defaults write com.apple.DebugSymbols DBGShellCommands /path/to/shellscript
% defaults write com.apple.DebugSymbols DBGFileMappedPaths ~/Library/SymbolCache/dsyms/uuids

We will only call your "/path/to/shellscript" if we didn't find an already cached symbol file in a symlink in "~/Library/SymbolCache/dsyms/uuids". This allows efficient caching and debugging...

This allows any company to implement a smart symbol finding and caching solution that matches their build systems.

Greg Clayton

This is fantastic information, thanks.

-- Joe Ranieri

Thanks Greg!

I wrote this up and put it on our Web page:

http://lldb.llvm.org/symbols.html