We should ship a debug SDK for linux

The official toolchains for linux do not include debug info for the SDK, even though all Swift code is built in debug mode by default. This is made all the more jarring because of the recent excellent work by @al45tair to add backtracing support on linux, eg I just saw this wonderful output when running into a swift-system regression with the latest trunk toolchain:

Test Case 'FilePathComponentsTest.testAdHocRRC' started at 2024-03-07 13:14:23.852
Swift/ArrayBufferProtocol.swift:175: Fatal error: invalid Collection: count differed in successive traversals

💣 Program crashed: Illegal instruction at 0x00007f1dc6f68d34

Thread 0 "swift-systemPac" crashed:

 0 0x00007f1dc6f68d34 closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 308 in libswiftCore.so
 1 0x00007f1dc6f68ae2 closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 257 in libswiftCore.so
 2 0x00007f1dc6f6899d closure #1 in _assertionFailure(_:_:file:line:flags:) + 380 in libswiftCore.so
 3 0x00007f1dc6f68526 _assertionFailure(_:_:file:line:flags:) + 229 in libswiftCore.so
 4 0x00007f1dc6f4e5fb closure #1 in _ArrayBufferProtocol.replaceSubrange<A>(_:with:elementsOf:) + 266 in libswiftCore.so
 5 0x00007f1dc71caed6 partial apply for closure #1 in _ArrayBufferProtocol.replaceSubrange<A>(_:with:elementsOf:) + 37 in libswiftCore.so
 6 0x00007f1dc6fa5273 Array.withContiguousStorageIfAvailable<A>(_:) + 50 in libswiftCore.so
 7 0x00007f1dc6f52439 Array.withContiguousStorageIfAvailable<A>(_:) + 8 in libswiftCore.so
 8 SystemString.withContiguousStorageIfAvailable<A>(_:) + 119 in swift-systemPackageTests.xctest at /home/fina/swift-system/Sources/System/SystemString.swift:149:31

   147│     _ body: (UnsafeBufferPointer<SystemChar>) throws -> R
   148│   ) rethrows -> R? {
   149│     try nullTerminatedStorage.withContiguousStorageIfAvailable(body)
      │                               ▲
   150│   }
   151│

 9 0x00007f1dc6f5110f Array.replaceSubrange<A>(_:with:) + 638 in libswiftCore.so
10 SystemString.replaceSubrange<A>(_:with:) + 166 in swift-systemPackageTests.xctest at /home/fina/swift-system/Sources/System/SystemString.swift:136:27

   134│   ) where C.Element == SystemChar {
   135│     defer { _invariantCheck() }
   136│     nullTerminatedStorage.replaceSubrange(subrange, with: newElements)
      │                           ▲
   137│   }
   138│

11 FilePath.ComponentView.replaceSubrange<A>(_:with:) + 1182 in swift-systemPackageTests.xctest at /home/fina/swift-system/Sources/System/FilePath/FilePathComponentView.swift:172:20

   170│       str.append(platformSeparator)
   171│     }
   172│     _path._storage.replaceSubrange(range, with: str)
      │                    ▲
   173│   }
   174│ }

12 0x00007f1dc6f57120 RangeReplaceableCollection.insert<A>(contentsOf:at:) + 639 in libswiftCore.so
13 closure #4 in FilePathComponentsTest.testAdHocRRC() + 486 in swift-systemPackageTests.xctest at /home/fina/swift-system/Tests/SystemTests/FilePathTests/FilePathComponentsTest.swift:153:23

   151│
   152│     restoreAfter {
   153│       path.components.insert(
      │                       ▲
   154│         contentsOf: ["bar", "baz"], at: path.components.startIndex)
   155│       expect("/bar/baz/usr/local/bin")

14 restoreAfter #1 (body:) in FilePathComponentsTest.testAdHocRRC() + 132 in swift-systemPackageTests.xctest at /home/fina/swift-system/Tests/SystemTests/FilePathTests/FilePathComponentsTest.swift:125:7

   123│       let copy = path
   124│       defer { path = copy }
   125│       body()
      │       ▲
   126│     }
   127│

15 FilePathComponentsTest.testAdHocRRC() + 237 in swift-systemPackageTests.xctest at /home/fina/swift-system/Tests/SystemTests/FilePathTests/FilePathComponentsTest.swift:152:5

   150│     }
   151│
   152│     restoreAfter {
      │     ▲
   153│       path.components.insert(
   154│         contentsOf: ["bar", "baz"], at: path.components.startIndex)

16 implicit closure #2 in implicit closure #1 in variable initialization expression of static FilePathComponentsTest.__allTests__FilePathComponentsTest + 26 in swift-systemPackageTests.xctest at /home/fina/swift-system/Tests/SystemTests/XCTestManifests.swift:42:26

    40│     // to regenerate.
    41│     static let __allTests__FilePathComponentsTest = [
    42│         ("testAdHocRRC", testAdHocRRC),
      │                          ▲
    43│         ("testCases", testCases),
    44│         ("testSeparatorNormalization", testSeparatorNormalization),

Backtrace took 0.19s

Illegal instruction (core dumped)

Note how I get great feedback on swift-system, but once it reaches the stdlib library libswiftCore, all I get is method names without line numbers. Of course, I can build a debug SDK myself, but we shouldn't require building the linux SDK from source for all devs.

@al45tair or @mishal_shah, any plans to add a debug SDK for linux to swift.org?

2 Likes

The ideal, actually, would be for us to turn on build IDs (which is on my TODO list), and then we could ship the debug information separately — the backtracer already knows how to find it in all the standard places (the only thing it doesn't do is the HTTP request thing).

6 Likes