Debugging Buck-built applications in Xcode requires special configuration to ensure breakpoints work correctly and source code is properly mapped. BuckSample includes BuckLocal integration that handles debug source path remapping automatically.
When debugging Buck-built binaries, especially those fetched from an HTTP cache or built on CI machines, LLDB (Xcode’s debugger) may not be able to find the source files because:
The binaries contain relative paths like ./
Libraries from HTTP cache may have absolute paths from the CI machine
LLDB needs absolute local paths to map breakpoints to addresses
#!/bin/bash## This script creates a UUID.plist file inside the dSym bundle, and uses its `DBGSourcePathRemapping` config# to remap remote pathes of apps repo to its local path.## This is essential to enable debugging libraries fetched from Http cache built by a CI machine. Without this# mapping, the breakpoints set locally won't work because LLDB won't be able to map those breakpoints to an address.## This is still needed even if no Http cache is used, because the binaries compiled by Buck has relative path `./` in them,# and LLDB needs absolute path to get breakpoints to work. However, if only `./` needs to be mapped, we may also use# the LLDB config `target.source-map` to get it working, to avoid the creation of a DSYM file.## We store all possible remote paths in a separate RemoteSourcePathList.txt file, so it's easier to maintain# the list without touching the logic of generating the plist file.#DSYM_BUNDLE_PATH=$DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME# Wait for 1 second to make sure the DSYM bundle had been generated.sleep 1# Use dwarfdump to get the UUID of the DWARF file in the dSym bundle.# The filename of the pList must match this UUID for the source path remapping to work.UUID=`dwarfdump --uuid $DSYM_BUNDLE_PATH | cut -d ' ' -f 2`# This is the path to the UUID.plist file we're about to create.DSYM_PLIST_PATH=$DSYM_BUNDLE_PATH/Contents/Resources/$UUID.plist# The following are 3 template files we use to construct the UUID.plistDSYM_PLIST_PREFIX="$REPO_ROOT/BuckLocal/SourcePathRemapping_Prefix"DSYM_PLIST_POSTFIX="$REPO_ROOT/BuckLocal/SourcePathRemapping_Postfix"REMOTE_PATH_LIST="$REPO_ROOT/BuckLocal/RemoteSourcePathList.txt"# Create the plist filetouch $DSYM_PLIST_PATH# For the prefix template, we simply copy its content over.cat $DSYM_PLIST_PREFIX > $DSYM_PLIST_PATH# For the main mapping, we use awk to print each remote path as a Key in the plist, and the actual local repo path as the Value, so that we can map all remote pathes to local repo root.cat $REMOTE_PATH_LIST | awk -v repo_root=$REPO_ROOT '{print "<key>"$1"</key><string>"repo_root"</string>"}' >> $DSYM_PLIST_PATH# For the postfix template, we also copy its content over to the plist file without modification.cat $DSYM_PLIST_POSTFIX >> $DSYM_PLIST_PATH
1
Extract UUID
Uses dwarfdump to extract the UUID from the dSYM bundle. The plist filename must match this UUID for LLDB to recognize it.
2
Build Plist File
Constructs a plist file with DBGSourcePathRemapping configuration using three template files:
SourcePathRemapping_Prefix: XML header and plist structure
RemoteSourcePathList.txt: List of remote paths to remap
SourcePathRemapping_Postfix: Closing XML tags
3
Map Paths
For each remote path in RemoteSourcePathList.txt, creates a mapping to the local repository root:
The BuckLocal/RemoteSourcePathList.txt file contains paths that need remapping:
BuckLocal/RemoteSourcePathList.txt
.
Currently it only remaps the relative path ./, but you can add additional paths if you’re using HTTP cache with binaries built on CI machines:
./var/ci/workspace/app/Users/ci-user/builds/app
If breakpoints aren’t working, check that the remote paths in RemoteSourcePathList.txt match the paths embedded in your cached binaries. Use dwarfdump --debug-info <binary> to inspect source paths in the debug info.