Added symbols page for Mac OS X that explains how DebugSymbols.framework can be customized.
llvm-svn: 168224
This commit is contained in:
parent
59c53c2e08
commit
6670c7e4b4
|
@ -20,6 +20,7 @@
|
|||
<li><a href="varformats.html">Variable Formatting</a></li>
|
||||
<li><a href="python-reference.html">Python Reference</a></li>
|
||||
<li><a href="scripting.html">Python Example</a></li>
|
||||
<li><a href="symbols.html">Symbols on Mac OS X</a></li>
|
||||
<li><a href="architecture.html">Architecture</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<link href="style.css" rel="stylesheet" type="text/css" />
|
||||
<title>Debug Sybmols on Mac OS X</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="www_title">
|
||||
The <strong>LLDB</strong> Debugger
|
||||
</div>
|
||||
|
||||
<div id="container">
|
||||
<div id="content">
|
||||
|
||||
<!--#include virtual="sidebar.incl"-->
|
||||
|
||||
<div id="middle">
|
||||
<div class="post">
|
||||
<h1 class="postheader">Debug Symbols on MacOSX</h1>
|
||||
<div class="postcontent">
|
||||
<p>On MacOSX, debug symbols are often in stand alone bundles called <b>dSYM</b> files.
|
||||
These are bundles that contain DWARF debug information and other resources related to
|
||||
builds and debug info.</p>
|
||||
<p>The DebugSymbols.framework framework helps locate dSYM files when given a UUID. It can
|
||||
locate the symbols using a variety of methods:</p>
|
||||
<ul>
|
||||
<li>Spotlight</li>
|
||||
<li>Explicit search paths</li>
|
||||
<li>Implicit search paths</li>
|
||||
<li>File mapped UUID paths</li>
|
||||
<li>Running one or more shell scripts</li>
|
||||
</ul>
|
||||
<p>DebugSymbols.framework also has global defaults that can be modified to allow
|
||||
all of the debug tools (lldb, gdb, sample, CoreSymbolication.framework) to easily
|
||||
find important debug symbols. The domain for the DebugSymbols.framework defaults
|
||||
is <b>com.apple.DebugSymbols</b>, and the defaults can be read, written or modified
|
||||
using the <b>defaults</b> shell command:
|
||||
<code><pre><tt><b>% defaults read com.apple.DebugSymbols
|
||||
% defaults write com.apple.DebugSymbols KEY ...
|
||||
% defaults delete com.apple.DebugSymbols KEY</b>
|
||||
</tt></pre></code>
|
||||
|
||||
<p>The following is a list of the defaults key value
|
||||
setting pairs that can be used to enhance symbol location:</p>
|
||||
<table class="stats" width="620" cellspacing="0">
|
||||
<tr>
|
||||
<td class="hed" width="20%">Defaults Key</td>
|
||||
<td class="hed" width="70%">Description</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGFileMappedPaths</b>
|
||||
</td>
|
||||
<td class="content">
|
||||
This default can be specified as a single string, or an array of strings.
|
||||
Each string represents a directory that contains file mapped UUID values
|
||||
that point to dSYM files. See the "File Mapped UUID Directories" section
|
||||
below for more details. Whenever DebugSymbols.framework is asked to lookup
|
||||
a dSYM file, it will first look in any file mapped UUID directories
|
||||
for a quick match.
|
||||
</td>
|
||||
</tr>
|
||||
<td class="content" colspan="2">
|
||||
<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGFileMappedPaths -string /path/to/uuidmap1</b>
|
||||
<b>% defaults write com.apple.DebugSymbols DBGFileMappedPaths -array /path/to/uuidmap1
|
||||
/path/to/uuidmap2</b>
|
||||
</tt></pre></code>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGShellCommands</b>
|
||||
</td>
|
||||
<td class="content">
|
||||
This default can be specified as a single string, or an array of strings.
|
||||
Specifies a shell script that will get run in order to find the dSYM.
|
||||
The shell script will be run given a single UUID value as the shell
|
||||
command arguments and the shell command is expected to return a property
|
||||
list. See the property list format defined below.
|
||||
</td>
|
||||
</tr>
|
||||
<td class="content" colspan="2">
|
||||
<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGShellCommands -string /path/to/script1</b>
|
||||
<b>% defaults write com.apple.DebugSymbols DBGShellCommands -array /path/to/script1
|
||||
/path/to/script2</b>
|
||||
</tt></pre></code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGSpotlightPaths</b>
|
||||
</td>
|
||||
<td class="content">
|
||||
Specifies the directories to limit spotlight searches to as a string or array of strings. When any
|
||||
other defaults are supplied to <b>com.apple.DebugSymbols</b>, spotlight
|
||||
searches will be disabled unless this default is set to an empty array:
|
||||
</td>
|
||||
</tr>
|
||||
<td class="content" colspan="2">
|
||||
<code><pre><tt><font color="green"># Specify an empty array to keep Spotlight searches enabled in all locations</font>
|
||||
<b>% defaults write com.apple.DebugSymbols DBGSpotlightPaths -array</b>
|
||||
|
||||
<font color="green"># Specify an array of paths to limit spotlight searches to certain directories</font>
|
||||
<b>% defaults write com.apple.DebugSymbols DBGSpotlightPaths -array /path/dir1 /path/dir2</b>
|
||||
</tt></pre></code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="postfooter"></div>
|
||||
</div>
|
||||
<div class="post">
|
||||
<h1 class="postheader">Shell Script Property List Format</h1>
|
||||
<div class="postcontent">
|
||||
<p>Shell scripts that are specified with the <b>DBGShellCommands</b> defaults key
|
||||
will be run in the order in which they are specified until a match is found.
|
||||
The shell script will be invoked with a single UUID string value like
|
||||
"23516BE4-29BE-350C-91C9-F36E7999F0F1". The shell script must respond with a
|
||||
property list being written to STDOUT. The property list must contain UUID
|
||||
string values as the root key values, with a dictionary for each UUID. The dictionaries
|
||||
can contain one or more of the following keys:
|
||||
|
||||
<table class="stats" width="620" cellspacing="0">
|
||||
<tr>
|
||||
<td class="hed" width="20%">Key</td>
|
||||
<td class="hed" width="70%">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGArchitecture</b>
|
||||
</td>
|
||||
<td class="content">A textual architecture or target triple like "x86_64", "i386", or "x86_64-apple-macosx".
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGBuildSourcePath</b>
|
||||
</td>
|
||||
<td class="content">A path prefix that was used when building the dSYM file. The debug information will
|
||||
contain paths with this prefix.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGSourcePath</b>
|
||||
</td>
|
||||
<td class="content">A path prefix for where the sources exist after the build has completed. Often when
|
||||
building projects, build machines will host the sources in a temporary directory while building, then
|
||||
move the sources to another location for archiving. If the paths in the debug info don't match where
|
||||
the sources are currently hosted, then specifying this path along with the <b>DBGBuildSourcePath</b>
|
||||
will help the developer tools always show you sources when debugging or symbolicating.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGDSYMPath</b>
|
||||
</td>
|
||||
<td class="content">A path to the dSYM mach-o file inside the dSYM bundle.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGSymbolRichExecutable</b>
|
||||
</td>
|
||||
<td class="content">A path to the symbol rich executable. Binaries are often stripped after
|
||||
being built and packaged into a release. If your build systems saves an unstripped executable
|
||||
a path to this executable can be provided.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<b>DBGError</b>
|
||||
</td>
|
||||
<td class="content">If a binary can not be located for the supplied UUID, a user readable error
|
||||
can be returned.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Below is a sample shell script output for a binary that contains two architectures:
|
||||
<code><pre><tt>
|
||||
<?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>
|
||||
<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>
|
||||
</dict>
|
||||
</plist>
|
||||
</tt></pre></code>
|
||||
|
||||
</div>
|
||||
<div class="postfooter"></div>
|
||||
</div>
|
||||
<div class="post">
|
||||
<h1 class="postheader">Embedding UUID property lists inside the dSYM bundles</h1>
|
||||
<div class="postcontent">
|
||||
<p>Since dSYM files are bundles, you can also place UUID info plists files inside
|
||||
your dSYM bundles in the <b>Contents/Resources</b> directory. One of the main
|
||||
reasons to create the UUID plists inside the dSYM bundles
|
||||
is that it will help LLDB and other developer tools show you source. LLDB currently
|
||||
knows how to check for these plist files so it can automatically remap the source
|
||||
location information in the debug info.
|
||||
|
||||
<p>If we take the two UUID values from the returns plist above, we can split
|
||||
them out and save then in the dSYM bundle:
|
||||
|
||||
<code><pre><tt><b>% ls /path/to/foo.dSYM/Contents/Resources</b>
|
||||
23516BE4-29BE-350C-91C9-F36E7999F0F1.plist
|
||||
A40597AA-5529-3337-8C09-D8A014EB1578.plist
|
||||
|
||||
<b>% cat /path/to/foo.dSYM/Contents/Resources/23516BE4-29BE-350C-91C9-F36E7999F0F1.plist</b>
|
||||
<?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>
|
||||
</tt></pre></code>
|
||||
|
||||
<p>Note that the output is very close to what is needed by shell script output,
|
||||
so making the results of your shell script will be 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.
|
||||
|
||||
|
||||
</div>
|
||||
<div class="postfooter"></div>
|
||||
</div>
|
||||
<div class="post">
|
||||
<h1 class="postheader">File Mapped UUID Directories</h1>
|
||||
<div class="postcontent">
|
||||
<p>File Mapped directories can be used for efficient dSYM file lookups for
|
||||
local or remote dSYM files. The UUID is broken up by splitting the first
|
||||
20 hex digits into 4 character chunks, and a directory is created for each
|
||||
chunk, and each subsequent directory is created inside the previous one.
|
||||
A symlink is then created whose name is the last 12 hex digits in the deepest
|
||||
directory. The symlinks value is a full path to the mach-o files inside the
|
||||
dSYM bundle which contains the DWARF. Whenever DebugSymbols.framework is asked
|
||||
to lookup a dSYM file, it will first look in any file mapped UUID directories
|
||||
for a quick match if the defaults are appropriately set.
|
||||
|
||||
<p>For example, if we take the sample UUID plist inforamtion from above, we
|
||||
can create a File Mapped UUID directory cache in <b>~/Library/SymbolCache/dsyms/uuids</b>.
|
||||
We can easily see how things are laid out:
|
||||
|
||||
<code><pre><tt><b>% find ~/Library/SymbolCache/dsyms/uuids -type l</b>
|
||||
~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1
|
||||
~/Library/SymbolCache/dsyms/uuids/A405/97AA/5529/3337/8C09/D8A014EB1578
|
||||
</tt></pre></code>
|
||||
|
||||
<p>The last entries in these file mapped directories are symlinks to the actual dsym mach file in the dsym bundle:
|
||||
|
||||
<code><pre><tt><b>% ls -lAF ~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1</b>
|
||||
~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1@ -> ../../../../../../dsyms/foo.dSYM/Contents/Resources/DWARF/foo
|
||||
</tt></pre></code>
|
||||
<p>Then you can also tell DebugSymbols to check this UUID file map cache using:
|
||||
|
||||
<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGFileMappedPaths ~/Library/SymbolCache/dsyms/uuids</b>
|
||||
</tt></pre></code>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="postfooter"></div>
|
||||
</div>
|
||||
<div class="post">
|
||||
<h1 class="postheader">dSYM Locating Shell Script Tips</h1>
|
||||
<div class="postcontent">
|
||||
|
||||
<p>One possible implementation of a dSYM finding shell script is to have the script
|
||||
download and cache files locally in a known location. Then create a UUID map
|
||||
for each UUID value that was found in a local UUID File Map cache so the next query for the dSYM
|
||||
file will be able to use the cached version. So the shell script is used to
|
||||
initially download and cache the file, and subsequent accesses will use the
|
||||
cache and avoid calling the shell script.
|
||||
|
||||
<p>Then the defaults for DebugSymbols.framework will entail enabling your shell script,
|
||||
enabling the file mapped path setting so that already downloaded dSYMS fill quickly
|
||||
be found without needing to run the shell script every time, and also leaving spotlight enabled
|
||||
so that other normal dSYM files are still found:
|
||||
|
||||
<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGShellCommands /path/to/shellscript
|
||||
% defaults write com.apple.DebugSymbols DBGFileMappedPaths ~/Library/SymbolCache/dsyms/uuids
|
||||
% defaults write com.apple.DebugSymbols DBGSpotlightPaths -array</b>
|
||||
</tt></pre></code>
|
||||
|
||||
Hopefully this helps explain how DebugSymbols.framework can help any company
|
||||
implement a smart symbol finding and caching with minimal overhead.
|
||||
</p>
|
||||
</div>
|
||||
<div class="postfooter"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue