# Improving swift-lldb support for Path Remappings

**URL:** <https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694>\
**Category:** LLDB\
**Created:** [April 5, 2019, 3:47pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694 "2019-04-05T15:47:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![DavidGoldman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davidgoldman/32/6931_2.png) [@DavidGoldman](https://forums.swift.org/u/DavidGoldman)\
**Post date:** [April 5, 2019, 3:47pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/1 "2019-04-05T15:47:51Z")

</div>

**Background:**

Xcode assumes absolute paths for everything, which makes it particularly inflexible for distributed and portable builds.

Bazel makes use of relative paths from a single execution root, meaning it may embed relative paths (not absolute paths) into binaries. This is a problem with debugging with Xcode: Xcode runs lldb from the `/` directory instead of execution root, meaning these relative paths can not be resolved. Thus, we need workarounds to remap the paths.

**Workarounds:**

In lldb, there are two main ways to remap source paths for a binary:

- `target.source-map`: Remap paths at the target level, we can set this globally for Xcode but it will apply to all projects
- dSYM `DBGSourcePathRemapping `: Remap paths at the module (dSYM) level

**Problem:** Remapping paths without dSYMs as dSYMs are costly in terms of time

dSYM remappings work incredibly well - for this reason, Bazel's Xcode integration currently requires dSYMs for Swift. However, they come at a major cost for incremental builds - linking together all debug information is expensive. For this reason I've been looking into no longer requiring dSYMs for Swift, but now I'm running into a problem that `target.source-map` can't solve.

**Underlying problem:** swift-lldb will try to load a `SwiftASTContext` from a `Module` and then try to resolve [Swift AST data](https://github.com/apple/swift-lldb/blob/67c85a3de122f8ba816d792639a57bfba99033df/source/Symbol/SwiftASTContext.cpp#L3914) from the [DWARFDebugMap](https://github.com/apple/swift-lldb/blob/f616ac4dc37730ceade007286c2fc972b3c0bcee/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp#L1478).

For Bazel, these paths are relative, so by default lldb will not be able to find them since Xcode runs lldb from `/`. However, `target.source-map` can't apply here as only a module is given to `SwiftASTContext`, not a target. And I'm trying to move away from requiring dSYMs, so that remapping option isn't here.

I'm not quite sure how to deal with this, any ideas? @Adrian_Prantl

Quick brainstorming:

- Some equivalent `target.source-map` lldb setting for modules
- Some equivalent to dSYM files that only contain remapping (is an empty dSYM file valid?)

---

<div class="post-metadata">

**Author:** ![Adrian\_Prantl](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/adrian_prantl/32/1582_2.png) [@Adrian\_Prantl](https://forums.swift.org/u/Adrian_Prantl)\
**Post date:** [April 5, 2019, 4:11pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/2 "2019-04-05T16:11:05Z")

</div>

There are several way to attack this problem.

A quick and dirty hack would be to modify the linker invocation. The AST filenames in DWARFDebugMap are N\_AST symbol table entries created by the linker for every `-add-ast-path` command line option. Since you control the build system, you should be able to edit the paths before sending them to the ld.

You could write a post-processing tool that edits the N\_AST stabs entries.

We could add a `symbols.obj-map` setting that work analogously to `target.source-map`. However, this brings up an interesting question. Regular object files are found by LLDB very similarly by following N\_OSO stabs entries. Why can LLDB find the `.o` files in your use-case, but not the AST files? (You can dump the symtab by running `dsymutil -s` on the binary.) I'd like to understand that before deciding on a solution first.

---

<div class="post-metadata">

**Author:** ![DavidGoldman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davidgoldman/32/6931_2.png) [@DavidGoldman](https://forums.swift.org/u/DavidGoldman)\
**Post date:** [April 5, 2019, 4:35pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/3 "2019-04-05T16:35:50Z")

</div>

Post-processing seems a bit overkill since as you said we can modify the invocation as we control the build system. We could make the invocation use absolute paths, in which case lldb should be able to find the binary (assuming it was linked locally).

For some reason the N\_OSO stabs refer to files by absolute paths even though AFAIK we only use relative paths when referring to `.a` and `.o` files for the linker, maybe those are explicitly made absolute before embedding, unlike the N\_AST entries?

---

<div class="post-metadata">

**Author:** ![Adrian\_Prantl](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/adrian_prantl/32/1582_2.png) [@Adrian\_Prantl](https://forums.swift.org/u/Adrian_Prantl)\
**Post date:** [April 5, 2019, 4:42pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/4 "2019-04-05T16:42:10Z")

</div>

Are the .o files passed as absolute paths to the linker? If yes, then that's where they come from. If no, I'd suspect the linker makes them absolute.

I'm currently (independently of this) working on eliminating the -add-ast-path option from the linker and instead embed the path directly into DWARF, in which case the Swift compiler would control the path and the build system wouldn't need to know about it.

---

<div class="post-metadata">

**Author:** ![DavidGoldman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davidgoldman/32/6931_2.png) [@DavidGoldman](https://forums.swift.org/u/DavidGoldman)\
**Post date:** [April 5, 2019, 4:49pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/5 "2019-04-05T16:49:06Z")

</div>

Nope, confirmed that we pass them as relative paths, the linker must be making them absolute (which makes sense as otherwise dsymutil/lldb would not be able to load them unless it knew the build root).

Anyways, I'll try making the add\_ast\_path absolute and report back.

---

<div class="post-metadata">

**Author:** ![AlanQuatermain](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alanquatermain/32/4693_2.png) [@AlanQuatermain](https://forums.swift.org/u/AlanQuatermain)\
**Post date:** [April 5, 2019, 5:59pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/6 "2019-04-05T17:59:11Z")

</div>

In my experience I've seen absolute paths for Bazel-produced debug symbols, i.e. `/var/tmp/_jdovey_xxxxxxxx/<uuid>/execroot/ __main__ /…`. I've been using `-fdebug-prefix-map` (and `-debug-prefix-map` in swiftc v5) when invoked from Xcode to change these to match Xcode's expectations.

---

<div class="post-metadata">

**Author:** ![dmaclach](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dmaclach/32/6934_2.png) [@dmaclach](https://forums.swift.org/u/dmaclach)\
**Post date:** [April 5, 2019, 6:21pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/7 "2019-04-05T18:21:47Z")

</div>

Regarding the linker making absolute paths in N\_OSO stabs, I'd look in

[https://opensource.apple.com/source/ld64/ld64-409.12/src/ld/OutputFile.cpp.auto.html](https://opensource.apple.com/source/ld64/ld64-409.12/src/ld/OutputFile.cpp.auto.html)

search for `assureFullPath`.

Not 100% sure that's it, but certainly a smoking gun 🔫

---

<div class="post-metadata">

**Author:** ![DavidGoldman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davidgoldman/32/6931_2.png) [@DavidGoldman](https://forums.swift.org/u/DavidGoldman)\
**Post date:** [April 5, 2019, 7:45pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/8 "2019-04-05T19:45:56Z")

</div>

Interesting, it appeared to work locally with swift-lldb built on the Swift 5.1 branch, but when I try to test with Xcode 10.2 I get an error with duplicate definitions (was this recently fixed between Swift 5.0 and 5.1?):

EDIT: This seems like an unrelated issue, this workaround appears to be working.

```swift
<module-includes>:3:9: note: in file included from <module-includes>:3:
#import "../../../../../../../../../<redacted 5 dirs>/FooInternal.h"
        ^

/private/var/tmp/_bazel_davg/c4ea4f0ebd1679d2e8a68dee5920b740/execroot/workspace/bazel-out/ios-x86_64-min10.0-applebin_ios-ios_x86_64-dbg/genfiles/<redacted 5 dirs>/Foo.modulemaps/../../../../../../../../../<redacted 5 dirs>/FooInternal.h:1:9: note: in file included from /private/var/tmp/_bazel_davg/c4ea4f0ebd1679d2e8a68dee5920b740/execroot/workspace/bazel-out/ios-x86_64-min10.0-applebin_ios-ios_x86_64-dbg/genfiles/<redacted 5 dirs>/Foo.modulemaps/../../../../../../../../../<redacted 5 dirs>/FooInternal.h:1:
#import "<redacted 5 dirs>/Foo.h"
        ^

error: /private/var/tmp/_bazel_davg/c4ea4f0ebd1679d2e8a68dee5920b740/execroot/workspace/<redacted 5 dirs>/Foo.h:140:1: error: duplicate interface definition for class 'FooClass'
@interface FooClass : NSObject
^

/private/var/tmp/_bazel_davg/c4ea4f0ebd1679d2e8a68dee5920b740/execroot/workspace/bazel-out/ios-x86_64-min10.0-applebin_ios-ios_x86_64-dbg/genfiles/<redacted 5 dirs>/Foo.modulemaps/../../../../../../../../../<redacted 5 dirs>/Foo.h:140:12: note: previous definition is here
@interface FooClass : NSObject

```

---

<div class="post-metadata">

**Author:** ![DavidGoldman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davidgoldman/32/6931_2.png) [@DavidGoldman](https://forums.swift.org/u/DavidGoldman)\
**Post date:** [May 4, 2020, 6:51pm UTC](https://forums.swift.org/t/improving-swift-lldb-support-for-path-remappings/22694/9 "2020-05-04T18:51:19Z")

</div>

Update here: there is an ld flag to make the OSO entries relative (see [milen.me — Appleâs Linker & Deterministic Builds](https://milen.me/writings/apple-linker-ld64-deterministic-builds-oso-prefix/)), it may be worth revisiting whether we can make the remapping work for the Swift module as well so we don't have to make the path absolute.
