swift-colab
swift-colab copied to clipboard
Extra slash in error stack trace
I was working on reproducing a crash in swift-reflection-mirror, and successfully reproduced it on a non-Apple platform. The stack trace for the runtime error has slightly incorrect formatting. I never accounted for this type of error message while making Swift-Colab, which is probably why it's improperly formatted. However, I can at least use the stack trace to investigate the crash in ReflectionMirror.
// Cell 1 - pulls from the "colab-crash-1" branch
%install '.package(url: "https://github.com/philipturner/swift-reflection-mirror", .branch("colab-crash-1"))' ReflectionMirror
@_spi(Reflection) import ReflectionMirror
print(_forEachField)
// Cell 2
struct ASimpleKPI {
var w = 1
}
struct AMixedKPI {
var string = "foo"
}
struct ANestedKPI {
var simple = ASimpleKPI()
var mixed = AMixedKPI()
}
// Cell 3
var x = ANestedKPI()
do {
var result: [PartialKeyPath<ANestedKPI>] = []
var out = [PartialKeyPath<ANestedKPI>]()
_forEachFieldWithKeyPath(of: ANestedKPI.self, options: .ignoreUnknown) { _, kp in
out.append(kp)
return true
}
for kp in out {
result.append(kp)
if x[keyPath: kp] is ASimpleKPI {
_forEachFieldWithKeyPath(of: ASimpleKPI.self, options: .ignoreUnknown) { _, nkp in
result.append(kp.appending(path: nkp as AnyKeyPath)!)
return true
}
} else if x[keyPath: kp] is AMixedKPI {
var out2 = [AnyKeyPath]()
_forEachFieldWithKeyPath(of: AMixedKPI.self, options: .ignoreUnknown) { _, nkp in
out2.append(nkp as AnyKeyPath)
return true
}
for nkp in out2 {
result.append(kp.appending(path: nkp)!)
}
}
}
}
// Cell 4
do {
var result: [PartialKeyPath<ANestedKPI>] = []
var out = [PartialKeyPath<ANestedKPI>]()
_forEachFieldWithKeyPath(of: ANestedKPI.self, options: .ignoreUnknown) { _, kp in
out.append(kp)
return true
}
for kp in out {
result.append(kp)
if x[keyPath: kp] is ASimpleKPI {
_forEachFieldWithKeyPath(of: ASimpleKPI.self, options: .ignoreUnknown) { _, nkp in
result.append(kp.appending(path: nkp as AnyKeyPath)!)
return true
}
} else if x[keyPath: kp] is AMixedKPI {
_forEachFieldWithKeyPath(of: AMixedKPI.self, options: .ignoreUnknown) { _, nkp in
result.append(kp.appending(path: nkp as AnyKeyPath)!)
return true
}
}
}
}
Run the cells in this order:
- Cell 1
- Cell 2
- Cell 3
- Cell 4
- Cell 3
- Cell 4
In the second run of Cell 4, there should be a runtime crash. The error message's second stack frame says ReflectionMirror.swift/
, with an extraneous slash after swift
. The bug occurs in the function prettyPrintStackTrace
, inside the file FormatErrors.swift. Permalink here.

On second examination, the first frame is also incorrect at closure #3 in
. There are two spaces between in
and -
, when I would like only one present.
Patched in Swift-Colab v2.3. I rewrote the serialization mechanism. Instead of relying on null terminators to denote ends of strings, I put their length as a 4-byte header. Then, I removed the null terminator. Each header had to restart at a 4-byte boundary, which required aligning memory addresses with ~3 & (x + 3)
.

To fix the double-spaced function name, I added "main" to it. Whenever LLDB encounters a closure, it writes closure #N in
+ (space) + (whatever contexts it appears in). I guess it couldn't detect the context. The example below shows more types of contexts that can appear after "in":
