@descryy/runtime-adapter-swift 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ export type { RawSwiftFrame } from "./swift-frame-parsing.ts";
2
+ export { createSwiftLineClassifier, isSwiftCrashedThreadLine, isSwiftFrameLine, isSwiftHeaderLine, isSwiftThreadLine, isSwiftUnsymbolicatedFrameLine, parseSwiftFrame, parseSwiftHeaderPosition, } from "./swift-frame-parsing.ts";
3
+ export { createSwiftSourceLocationResolver } from "./swift-source-location-resolver.ts";
4
+ export { createSwiftStackTraceParser } from "./swift-stack-trace-parser.ts";
5
+ export type { SwiftRuntimeAdapterOptions } from "./swift-runtime-adapter.ts";
6
+ export { createSwiftRuntimeAdapter } from "./swift-runtime-adapter.ts";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC9B,eAAe,EACf,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { createSwiftLineClassifier, isSwiftCrashedThreadLine, isSwiftFrameLine, isSwiftHeaderLine, isSwiftThreadLine, isSwiftUnsymbolicatedFrameLine, parseSwiftFrame, parseSwiftHeaderPosition, } from "./swift-frame-parsing.js";
2
+ export { createSwiftSourceLocationResolver } from "./swift-source-location-resolver.js";
3
+ export { createSwiftStackTraceParser } from "./swift-stack-trace-parser.js";
4
+ export { createSwiftRuntimeAdapter } from "./swift-runtime-adapter.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC9B,eAAe,EACf,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Swift crash-handler trace line shapes — the `LineClassifier` for
3
+ * `ExceptionBlockDetector` plus the raw-text-to-frame-parts extraction
4
+ * that feeds `SourceLocationResolver`.
5
+ *
6
+ * Grammar verified against two things in `swiftlang/swift` itself, not
7
+ * memory or a blog post:
8
+ *
9
+ * - `test/Backtracing/FatalError.swift` — a real `FileCheck` test the
10
+ * Swift project's own CI compiles, runs, and crashes on purpose,
11
+ * asserting the exact backtrace text against the real interpreter's
12
+ * output. This is the same category of source `ruby/spec` was for
13
+ * RT-038 and `php-src`'s `.phpt` suite was for RT-040: interpreter-
14
+ * verified, not merely documented.
15
+ * - `stdlib/public/runtime/RuntimeErrorReporting.cpp` — confirms frame
16
+ * symbols are demangled by the runtime's own embedded demangler
17
+ * (`demangleSymbolAsString`) before being printed, which matters for
18
+ * what "mangled names" turns out to mean here — see point 4.
19
+ *
20
+ * No `swift` toolchain ran here; see `test/fixtures/PROVENANCE.md`.
21
+ *
22
+ * 1. **Header and first frame are separated by TWO fixed bridging lines,
23
+ * not one** — a shape none of this seam's other languages have had.
24
+ * `Fatal error: <message>` is followed by `*** Program crashed: <reason>
25
+ * at 0x<addr> ***`, then `Thread N [...] crashed:`, then (per the
26
+ * `FileCheck` test's plain `CHECK` rather than `CHECK-NEXT` between
27
+ * the thread line and frame 0) a blank line, before real frames start.
28
+ * PHP needed one bridging line (`Stack trace:`); C#'s `InnerException`
29
+ * case needed one (` ---> `). Swift needs two, plus tolerating a blank
30
+ * line — the same family of gap, escalated. Reported via
31
+ * `LineClassifier.isBridge` (RT-048), which `ExceptionBlockDetector`
32
+ * only ever consults while a header is already being held, so neither
33
+ * bridging line can open a block from idle on its own —
34
+ * `createSwiftLineClassifier` tracks a small stage counter (which of
35
+ * the two bridge lines is next) rather than a single boolean, since
36
+ * "confirm bridge line 1, then bridge line 2" is a short sequence, not
37
+ * a single yes/no; `isFrame` itself stays a plain, stateless check for
38
+ * the real frame shape.
39
+ * 2. **A frame is `<index> [flags]* 0x<addr> <symbol> + <offset> in
40
+ * <image>`, optionally ` at <file>:<line>:<col>`.** Index 0 is the
41
+ * innermost frame (the trap site itself) and the sequence counts
42
+ * upward to the process entry point — most-recent-first already, the
43
+ * same convention as V8/JVM/Go/Rust/C#; CPython remains the only
44
+ * reversing outlier in this codebase. `[ra]` and `[system]` are real,
45
+ * disclosed flags (a return-address frame; a Swift-runtime-internal
46
+ * frame) and are not stripped — they stay in `raw`, and are not
47
+ * parsed into anything structured because nothing in this contract
48
+ * has a field for them.
49
+ * 3. **The location suffix can be a real `file:line:col`, or a pseudo-path
50
+ * with neither** — `<compiler-generated>` for a compiler-synthesized
51
+ * frame (confirmed verbatim in the cited test: `static
52
+ * FatalError.$main() ... at {{.*}}/<compiler-generated>`), the same
53
+ * "real text, not a real source position" case CPython's pseudo-files
54
+ * already established a precedent for. Both shapes are handled: a
55
+ * `file:line:col` suffix is parsed into real fields; anything else
56
+ * after `at ` is kept as `file` verbatim with `line`/`column` null,
57
+ * never a fabricated position.
58
+ * 4. **"Mangled symbol names" turns out to mean something narrower than
59
+ * it sounds, verified rather than assumed from the lane brief.**
60
+ * `RuntimeErrorReporting.cpp`'s `dumpStackTraceEntry` demangles via
61
+ * `__cxa_demangle`/Swift's own `demangleSymbolAsString` automatically
62
+ * whenever symbol lookup succeeds — no external `swift-demangle`
63
+ * binary is needed, and the cited test's own frames are all
64
+ * already-demangled (`level5()`, `static FatalError.main()`). A raw
65
+ * `$s...`-prefixed name surviving into this text specifically means
66
+ * the runtime's own demangler failed on it, not that demangling was
67
+ * skipped. This parser does not attempt demangling itself either way
68
+ * — whatever text is there, verbatim, is `functionName`.
69
+ */
70
+ export interface RawSwiftFrame {
71
+ /** Whatever text the runtime printed for this frame — demangled, a fallback token, or (rarely) still mangled. Never rewritten. */
72
+ readonly functionName: string | null;
73
+ /** Null for a frame with no `at ...` location suffix at all (no debug info available for that image). */
74
+ readonly file: string | null;
75
+ /** Null when `file` is null, OR when `file` is a pseudo-path like `<compiler-generated>` with no real line. */
76
+ readonly line: number | null;
77
+ readonly column: number | null;
78
+ }
79
+ export declare function isSwiftHeaderLine(line: string): boolean;
80
+ export declare function isSwiftFrameLine(line: string): boolean;
81
+ /** True for a frame the backtracer printed but could not name — a real frame of a real stack, carrying only its address. */
82
+ export declare function isSwiftUnsymbolicatedFrameLine(line: string): boolean;
83
+ /** Any thread block header, `crashed` or not — what separates one thread's stack from another's. */
84
+ export declare function isSwiftThreadLine(line: string): boolean;
85
+ /** Only the thread that actually trapped. In a multi-thread dump the others precede it. */
86
+ export declare function isSwiftCrashedThreadLine(line: string): boolean;
87
+ /** The `file:line` the `Fatal error:` line declares, or null when it declares none. Never fabricated. */
88
+ export declare function parseSwiftHeaderPosition(line: string): {
89
+ readonly file: string;
90
+ readonly line: number;
91
+ } | null;
92
+ /**
93
+ * Stateful for the bridge between header and first frame (point 1 above),
94
+ * reported via `LineClassifier.isBridge` (RT-048).
95
+ *
96
+ * **RT-122 measured a real Swift 6.1.2 crash on Linux and the bridge is
97
+ * three lines, not two.** `*** Signal 4: Backtracing from 0x…... done ***`
98
+ * comes first, and the `FileCheck` test this was transcribed from does not
99
+ * contain it. Missing it was total rather than partial: the block closed
100
+ * before the first frame and a real Swift crash produced no evidence at
101
+ * all. The signal line is accepted as optional so both shapes work.
102
+ * `ExceptionBlockDetector` only ever consults `isBridge` while a header is
103
+ * already being held, so `*** Program crashed...` and `Thread N ...
104
+ * crashed:` cannot open a block on their own from idle — that guarantee is
105
+ * now the state machine's, not this classifier's to re-derive, which is
106
+ * what let `isFrame` shrink back to a plain, stateless check for the real
107
+ * frame shape: it no longer has to also recognise the bridge, only the
108
+ * thing that ends it.
109
+ *
110
+ * **Blank lines are tolerated at any point in the bridge, not just one.**
111
+ * The cited `FileCheck` test uses plain `CHECK:` (not `CHECK-NEXT:`)
112
+ * between the header, the two bridging lines, and frame 0, which permits
113
+ * — but does not confirm — a blank line at each gap; the test's own
114
+ * comment formatting cannot be trusted to mirror the real output's
115
+ * spacing. Rather than guess a specific count and position, every stage
116
+ * of the bridge accepts an arbitrary run of blank lines before the
117
+ * pattern it expects.
118
+ */
119
+ export declare function createSwiftLineClassifier(): {
120
+ isHeader(line: string): boolean;
121
+ isFrame(line: string): boolean;
122
+ isBridge(line: string): boolean;
123
+ };
124
+ /** `null` for anything not shaped like a real crash-handler frame — never fabricated. */
125
+ export declare function parseSwiftFrame(line: string): RawSwiftFrame | null;
126
+ //# sourceMappingURL=swift-frame-parsing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-frame-parsing.d.ts","sourceRoot":"","sources":["../src/swift-frame-parsing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH,MAAM,WAAW,aAAa;IAC5B,kIAAkI;IAClI,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,yGAAyG;IACzG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+GAA+G;IAC/G,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAsGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,4HAA4H;AAC5H,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,oGAAoG;AACpG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO9G;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,yBAAyB,IAAI;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAyEA;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAqClE"}
@@ -0,0 +1,330 @@
1
+ /**
2
+ * Swift crash-handler trace line shapes — the `LineClassifier` for
3
+ * `ExceptionBlockDetector` plus the raw-text-to-frame-parts extraction
4
+ * that feeds `SourceLocationResolver`.
5
+ *
6
+ * Grammar verified against two things in `swiftlang/swift` itself, not
7
+ * memory or a blog post:
8
+ *
9
+ * - `test/Backtracing/FatalError.swift` — a real `FileCheck` test the
10
+ * Swift project's own CI compiles, runs, and crashes on purpose,
11
+ * asserting the exact backtrace text against the real interpreter's
12
+ * output. This is the same category of source `ruby/spec` was for
13
+ * RT-038 and `php-src`'s `.phpt` suite was for RT-040: interpreter-
14
+ * verified, not merely documented.
15
+ * - `stdlib/public/runtime/RuntimeErrorReporting.cpp` — confirms frame
16
+ * symbols are demangled by the runtime's own embedded demangler
17
+ * (`demangleSymbolAsString`) before being printed, which matters for
18
+ * what "mangled names" turns out to mean here — see point 4.
19
+ *
20
+ * No `swift` toolchain ran here; see `test/fixtures/PROVENANCE.md`.
21
+ *
22
+ * 1. **Header and first frame are separated by TWO fixed bridging lines,
23
+ * not one** — a shape none of this seam's other languages have had.
24
+ * `Fatal error: <message>` is followed by `*** Program crashed: <reason>
25
+ * at 0x<addr> ***`, then `Thread N [...] crashed:`, then (per the
26
+ * `FileCheck` test's plain `CHECK` rather than `CHECK-NEXT` between
27
+ * the thread line and frame 0) a blank line, before real frames start.
28
+ * PHP needed one bridging line (`Stack trace:`); C#'s `InnerException`
29
+ * case needed one (` ---> `). Swift needs two, plus tolerating a blank
30
+ * line — the same family of gap, escalated. Reported via
31
+ * `LineClassifier.isBridge` (RT-048), which `ExceptionBlockDetector`
32
+ * only ever consults while a header is already being held, so neither
33
+ * bridging line can open a block from idle on its own —
34
+ * `createSwiftLineClassifier` tracks a small stage counter (which of
35
+ * the two bridge lines is next) rather than a single boolean, since
36
+ * "confirm bridge line 1, then bridge line 2" is a short sequence, not
37
+ * a single yes/no; `isFrame` itself stays a plain, stateless check for
38
+ * the real frame shape.
39
+ * 2. **A frame is `<index> [flags]* 0x<addr> <symbol> + <offset> in
40
+ * <image>`, optionally ` at <file>:<line>:<col>`.** Index 0 is the
41
+ * innermost frame (the trap site itself) and the sequence counts
42
+ * upward to the process entry point — most-recent-first already, the
43
+ * same convention as V8/JVM/Go/Rust/C#; CPython remains the only
44
+ * reversing outlier in this codebase. `[ra]` and `[system]` are real,
45
+ * disclosed flags (a return-address frame; a Swift-runtime-internal
46
+ * frame) and are not stripped — they stay in `raw`, and are not
47
+ * parsed into anything structured because nothing in this contract
48
+ * has a field for them.
49
+ * 3. **The location suffix can be a real `file:line:col`, or a pseudo-path
50
+ * with neither** — `<compiler-generated>` for a compiler-synthesized
51
+ * frame (confirmed verbatim in the cited test: `static
52
+ * FatalError.$main() ... at {{.*}}/<compiler-generated>`), the same
53
+ * "real text, not a real source position" case CPython's pseudo-files
54
+ * already established a precedent for. Both shapes are handled: a
55
+ * `file:line:col` suffix is parsed into real fields; anything else
56
+ * after `at ` is kept as `file` verbatim with `line`/`column` null,
57
+ * never a fabricated position.
58
+ * 4. **"Mangled symbol names" turns out to mean something narrower than
59
+ * it sounds, verified rather than assumed from the lane brief.**
60
+ * `RuntimeErrorReporting.cpp`'s `dumpStackTraceEntry` demangles via
61
+ * `__cxa_demangle`/Swift's own `demangleSymbolAsString` automatically
62
+ * whenever symbol lookup succeeds — no external `swift-demangle`
63
+ * binary is needed, and the cited test's own frames are all
64
+ * already-demangled (`level5()`, `static FatalError.main()`). A raw
65
+ * `$s...`-prefixed name surviving into this text specifically means
66
+ * the runtime's own demangler failed on it, not that demangling was
67
+ * skipped. This parser does not attempt demangling itself either way
68
+ * — whatever text is there, verbatim, is `functionName`.
69
+ */
70
+ /** Not anchored to the start of the line, same reasoning as every other adapter's header pattern: a logger prefix may precede it. */
71
+ const HEADER_PATTERN = /Fatal error: (?<message>.+)$/;
72
+ const PROGRAM_CRASHED_PATTERN = /^\*\*\* Program crashed: .+ \*\*\*$/;
73
+ /**
74
+ * `*** Signal 4: Backtracing from 0x787be4d66895... done ***` — the
75
+ * backtracer announcing itself, printed BEFORE `*** Program crashed ***`.
76
+ *
77
+ * **Measured on a real Swift 6.1.2 crash on Linux (RT-122); it is not in
78
+ * the `FileCheck` test this adapter was transcribed from.** Its absence
79
+ * from the bridge was total: the held header met a line matching nothing,
80
+ * the block closed before a single frame, and a real Swift crash produced
81
+ * no evidence at all — not an error, no evidence.
82
+ *
83
+ * Optional rather than required, because the transcribed fixtures (and
84
+ * whatever produced them) do not have it, and a bridge that demands it
85
+ * would trade one silence for another.
86
+ */
87
+ const SIGNAL_BACKTRACING_PATTERN = /^\*\*\* Signal \d+: Backtracing from 0x[0-9a-fA-F]+\.\.\. done \*\*\*$/;
88
+ /**
89
+ * A thread block's own header: `Thread 1 crashed:`, `Thread 0 "server"
90
+ * crashed:`, or — **measured, and the transcribed fixtures have no such
91
+ * case** — `Thread 0 "server":` with no `crashed` at all.
92
+ *
93
+ * When the trap happens off the main thread, Swift dumps *every* thread and
94
+ * only one carries `crashed`. The uncrashed ones come first. So the two
95
+ * spellings are different facts, not formatting: `isSwiftCrashedThreadLine`
96
+ * is what says which stack actually trapped.
97
+ */
98
+ const THREAD_PATTERN = /^Thread \d+(?:\s+"[^"]*")?(?:\s+crashed)?:\s*$/;
99
+ const THREAD_CRASHED_PATTERN = /^Thread \d+.*crashed:\s*$/;
100
+ /**
101
+ * The position Swift's own `Fatal error:` line declares:
102
+ * `server/server.swift:10: Fatal error: Unexpectedly found nil …`.
103
+ *
104
+ * `#file` defaults to `Module/File.swift`, so requiring the `.swift`
105
+ * extension keeps this from matching a `log`-style `02:11:06` timestamp.
106
+ * The transcribed fixtures carry no position at all — that is a real
107
+ * difference between the two shapes, and it degrades to "no declared
108
+ * position" rather than to a guess.
109
+ */
110
+ const HEADER_POSITION_PATTERN = /(?<file>\S+\.swift):(?<line>\d+):\s+Fatal error:/;
111
+ /**
112
+ * `<index> [flag]* 0x<hex> <symbol> + <offset> in <image>[ at <location>]`.
113
+ * The mandatory `0x<hex address>` in the middle is what makes this safe
114
+ * against the numbered-log-line hazard the rest of this lane's adapters
115
+ * were warned about (PHP's `#N`, C#'s bare `at`): an ordinary numbered
116
+ * status line never contains a hex address in this exact position.
117
+ * `symbol` is greedy — correct because the ` + <offset> in <image>`
118
+ * suffix is anchored and unique per line, so backtracking finds it
119
+ * regardless of what the symbol text itself contains.
120
+ */
121
+ const FRAME_PATTERN = /^\d+\s+(?:\[[\w-]+\]\s+)*0x[0-9a-fA-F]+\s+(?<symbol>.+?)(?:\s\+\s\d+)?\s+in\s+(?<image>\S+)(?:\s+at\s+(?<location>.+))?\s*$/;
122
+ /**
123
+ * **`+ <offset>` is optional, and requiring it took CI red (RT-133).**
124
+ *
125
+ * Swift prints `<symbol> + <offset> in <image>` for a frame it can name and
126
+ * `<unknown> in <image>` — no offset — for one it cannot. Every frame in the
127
+ * 6.1.2 dump this parser was built against had an offset, because this
128
+ * machine has libc symbols; the CI runner does not, so `Thread 0`'s first
129
+ * frame is `<unknown> in libc.so.6`. `isSwiftFrameLine` gates
130
+ * `LineClassifier.isFrame`, so the block closed on that line, at 247
131
+ * characters, and the crashed thread three blocks below was never captured.
132
+ *
133
+ * `symbol` became lazy (`.+?`) with the offset optional. Greedy plus
134
+ * optional would let `.+` swallow ` + 309` and report the offset as part of
135
+ * the function name.
136
+ */
137
+ const UNNAMED_SYMBOL = "<unknown>";
138
+ /**
139
+ * The same line with **no symbol at all**: `4 [ra] 0x00005b3df1642b54`.
140
+ *
141
+ * **Measured, and it is what took CI red (RT-126).** Swift's backtracer
142
+ * symbolicates against the binary's debug info while printing; when it
143
+ * cannot — `symbolicate=off`, or an environment where the images are not
144
+ * readable — it still unwinds correctly and prints every frame as an
145
+ * address. The GitHub runner's first-ever Swift run produced exactly this
146
+ * and `FRAME_PATTERN` matched none of it.
147
+ *
148
+ * The cost was **not** just unparsed frames. `isSwiftFrameLine` gates
149
+ * `LineClassifier.isFrame`, so the exception block closed at the thread
150
+ * header and `payload.raw` was **247 characters** — the addresses were
151
+ * never captured either, so nothing downstream could resolve them offline.
152
+ * A degradation that also destroys the evidence of itself.
153
+ *
154
+ * Safe against the numbered-log-line hazard for the same reason
155
+ * `FRAME_PATTERN` is, and anchored at both ends so it cannot swallow the
156
+ * `Registers:` and `Images:` sections that follow the crashed thread in the
157
+ * same slice: register lines begin with a register name (`rax`, ` r8`) and
158
+ * image lines with `0x`, so neither can present a leading frame index.
159
+ * Asserted, not assumed — see this package's unsymbolicated-dump test.
160
+ */
161
+ const UNSYMBOLICATED_FRAME_PATTERN = /^\d+\s+(?:\[[\w-]+\]\s+)*0x[0-9a-fA-F]+\s*$/;
162
+ /** A real source position: `file:line:col`. Anchored at both ends so a bare pseudo-path like `<compiler-generated>` never matches. */
163
+ const FILE_LINE_COL_PATTERN = /^(?<file>.+):(?<line>\d+):(?<col>\d+)$/;
164
+ export function isSwiftHeaderLine(line) {
165
+ return HEADER_PATTERN.test(line);
166
+ }
167
+ export function isSwiftFrameLine(line) {
168
+ return FRAME_PATTERN.test(line) || UNSYMBOLICATED_FRAME_PATTERN.test(line);
169
+ }
170
+ /** True for a frame the backtracer printed but could not name — a real frame of a real stack, carrying only its address. */
171
+ export function isSwiftUnsymbolicatedFrameLine(line) {
172
+ return !FRAME_PATTERN.test(line) && UNSYMBOLICATED_FRAME_PATTERN.test(line);
173
+ }
174
+ /** Any thread block header, `crashed` or not — what separates one thread's stack from another's. */
175
+ export function isSwiftThreadLine(line) {
176
+ return THREAD_PATTERN.test(line);
177
+ }
178
+ /** Only the thread that actually trapped. In a multi-thread dump the others precede it. */
179
+ export function isSwiftCrashedThreadLine(line) {
180
+ return THREAD_CRASHED_PATTERN.test(line);
181
+ }
182
+ /** The `file:line` the `Fatal error:` line declares, or null when it declares none. Never fabricated. */
183
+ export function parseSwiftHeaderPosition(line) {
184
+ const match = HEADER_POSITION_PATTERN.exec(line);
185
+ if (!match?.groups)
186
+ return null;
187
+ const file = match.groups["file"];
188
+ const lineNumber = Number(match.groups["line"]);
189
+ if (file === undefined || !Number.isInteger(lineNumber))
190
+ return null;
191
+ return { file, line: lineNumber };
192
+ }
193
+ /**
194
+ * Stateful for the bridge between header and first frame (point 1 above),
195
+ * reported via `LineClassifier.isBridge` (RT-048).
196
+ *
197
+ * **RT-122 measured a real Swift 6.1.2 crash on Linux and the bridge is
198
+ * three lines, not two.** `*** Signal 4: Backtracing from 0x…... done ***`
199
+ * comes first, and the `FileCheck` test this was transcribed from does not
200
+ * contain it. Missing it was total rather than partial: the block closed
201
+ * before the first frame and a real Swift crash produced no evidence at
202
+ * all. The signal line is accepted as optional so both shapes work.
203
+ * `ExceptionBlockDetector` only ever consults `isBridge` while a header is
204
+ * already being held, so `*** Program crashed...` and `Thread N ...
205
+ * crashed:` cannot open a block on their own from idle — that guarantee is
206
+ * now the state machine's, not this classifier's to re-derive, which is
207
+ * what let `isFrame` shrink back to a plain, stateless check for the real
208
+ * frame shape: it no longer has to also recognise the bridge, only the
209
+ * thing that ends it.
210
+ *
211
+ * **Blank lines are tolerated at any point in the bridge, not just one.**
212
+ * The cited `FileCheck` test uses plain `CHECK:` (not `CHECK-NEXT:`)
213
+ * between the header, the two bridging lines, and frame 0, which permits
214
+ * — but does not confirm — a blank line at each gap; the test's own
215
+ * comment formatting cannot be trusted to mirror the real output's
216
+ * spacing. Rather than guess a specific count and position, every stage
217
+ * of the bridge accepts an arbitrary run of blank lines before the
218
+ * pattern it expects.
219
+ */
220
+ export function createSwiftLineClassifier() {
221
+ /**
222
+ * 0 = not bridging; 1 = expecting the signal line OR "*** Program
223
+ * crashed"; 2 = signal seen, expecting "*** Program crashed"; 3 =
224
+ * expecting the first "Thread N ...:" line.
225
+ *
226
+ * Three stages rather than RT-048's two, because the real backtracer
227
+ * prints one more line than the transcribed fixtures do. Stage 1 accepts
228
+ * either, which is what makes the signal line optional without a
229
+ * separate code path.
230
+ */
231
+ let stage = 0;
232
+ /**
233
+ * Whether a thread stack is currently open.
234
+ *
235
+ * **`isFrame` is consulted from `idle` too** (`ExceptionBlockDetector`
236
+ * opens a bare `stack-trace` block on one), so the blank-line and
237
+ * thread-header tolerance below MUST be gated on having already seen a
238
+ * real frame or a bridged thread line. Ungated, every blank line in
239
+ * ordinary output would open a block.
240
+ */
241
+ let inStack = false;
242
+ return {
243
+ isHeader(line) {
244
+ if (isSwiftHeaderLine(line)) {
245
+ stage = 1;
246
+ inStack = false;
247
+ return true;
248
+ }
249
+ return false;
250
+ },
251
+ isFrame(line) {
252
+ // A real frame always ends the bridge, wherever it currently stands.
253
+ if (isSwiftFrameLine(line)) {
254
+ stage = 0;
255
+ inStack = true;
256
+ return true;
257
+ }
258
+ // **A crash off the main thread dumps every thread**, and the one
259
+ // that trapped is not first — measured (RT-122). Without accepting
260
+ // the intervening blank and `Thread N ...:` lines, the block ends at
261
+ // the first thread boundary and keeps only the stack of a thread that
262
+ // did not crash. Which thread's frames are then USED is the parser's
263
+ // decision, not this one's; this only keeps them in the block.
264
+ if (inStack && (line.trim() === "" || isSwiftThreadLine(line)))
265
+ return true;
266
+ inStack = false;
267
+ return false;
268
+ },
269
+ isBridge(line) {
270
+ if (line.trim() === "")
271
+ return true; // blank lines never advance or reset the stage
272
+ if (stage === 1 && SIGNAL_BACKTRACING_PATTERN.test(line)) {
273
+ stage = 2;
274
+ return true;
275
+ }
276
+ if ((stage === 1 || stage === 2) && PROGRAM_CRASHED_PATTERN.test(line)) {
277
+ stage = 3;
278
+ return true;
279
+ }
280
+ if (stage === 3 && isSwiftThreadLine(line)) {
281
+ stage = 0;
282
+ // The block has not opened yet — the next line is a blank, then
283
+ // frame 0 — so the stack is already "open" as far as isFrame is
284
+ // concerned, or that blank would close what the bridge just built.
285
+ inStack = true;
286
+ return true;
287
+ }
288
+ stage = 0;
289
+ return false;
290
+ },
291
+ };
292
+ }
293
+ /** `null` for anything not shaped like a real crash-handler frame — never fabricated. */
294
+ export function parseSwiftFrame(line) {
295
+ const match = FRAME_PATTERN.exec(line);
296
+ if (!match?.groups) {
297
+ // An unsymbolicated frame names nothing, and every field says so
298
+ // rather than one of them carrying the address as a stand-in. The
299
+ // frame's own text is kept verbatim as `StackFrame.raw` by the caller,
300
+ // which is where an address belongs — it is evidence, not a location.
301
+ return UNSYMBOLICATED_FRAME_PATTERN.test(line) ? { functionName: null, file: null, line: null, column: null } : null;
302
+ }
303
+ const symbol = match.groups["symbol"];
304
+ if (symbol === undefined)
305
+ return null;
306
+ // **`<unknown>` is the backtracer saying it has no name, so neither do
307
+ // we.** Passing the literal through would put a symbol into evidence that
308
+ // resolves against no graph node and reads, to anything downstream, like
309
+ // a function actually called that. `SourceLocation.functionName` is
310
+ // nullable for exactly this.
311
+ const named = symbol === UNNAMED_SYMBOL ? null : symbol;
312
+ const location = match.groups["location"];
313
+ if (location === undefined) {
314
+ // No `at ...` suffix at all — this image had no debug info to offer.
315
+ return { functionName: named, file: null, line: null, column: null };
316
+ }
317
+ const withLineCol = FILE_LINE_COL_PATTERN.exec(location);
318
+ if (withLineCol?.groups) {
319
+ const file = withLineCol.groups["file"];
320
+ const lineNumber = Number(withLineCol.groups["line"]);
321
+ const columnNumber = Number(withLineCol.groups["col"]);
322
+ if (file !== undefined && Number.isInteger(lineNumber) && Number.isInteger(columnNumber)) {
323
+ return { functionName: named, file, line: lineNumber, column: columnNumber };
324
+ }
325
+ }
326
+ // A pseudo-path (`<compiler-generated>`) or an otherwise unparseable
327
+ // location — real text, kept verbatim as `file`, never a fabricated line.
328
+ return { functionName: named, file: location, line: null, column: null };
329
+ }
330
+ //# sourceMappingURL=swift-frame-parsing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-frame-parsing.js","sourceRoot":"","sources":["../src/swift-frame-parsing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The concrete `RuntimeAdapter` for Swift.
3
+ *
4
+ * Needed no seam change: RT-037's already-nullable `SourceLocation`/
5
+ * `RawFrameLocation` fields are what let a no-debug-info frame attach to
6
+ * a real `null` location instead of a fabricated one. See
7
+ * `swift-frame-parsing.ts` for the two-line header/first-frame bridge
8
+ * this language needed from the classifier — the longest such bridge in
9
+ * this seam so far (PHP needed one line, C#'s `InnerException` needed
10
+ * one; Swift needs two, plus a tolerated blank line).
11
+ */
12
+ import type { RuntimeAdapter } from "@descryy/runtime-backend-observation";
13
+ export interface SwiftRuntimeAdapterOptions {
14
+ /** Attributed on every emitted Evidence's `service` field (plan §16.7). Omit when not applicable. */
15
+ readonly service?: string;
16
+ }
17
+ export declare function createSwiftRuntimeAdapter(options?: SwiftRuntimeAdapterOptions): RuntimeAdapter;
18
+ //# sourceMappingURL=swift-runtime-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-runtime-adapter.d.ts","sourceRoot":"","sources":["../src/swift-runtime-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,sCAAsC,CAAC;AAQhG,MAAM,WAAW,0BAA0B;IACzC,qGAAqG;IACrG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,cAAc,CAwBlG"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The concrete `RuntimeAdapter` for Swift.
3
+ *
4
+ * Needed no seam change: RT-037's already-nullable `SourceLocation`/
5
+ * `RawFrameLocation` fields are what let a no-debug-info frame attach to
6
+ * a real `null` location instead of a fabricated one. See
7
+ * `swift-frame-parsing.ts` for the two-line header/first-frame bridge
8
+ * this language needed from the classifier — the longest such bridge in
9
+ * this seam so far (PHP needed one line, C#'s `InnerException` needed
10
+ * one; Swift needs two, plus a tolerated blank line).
11
+ */
12
+ import { createLogCollector } from "@descryy/runtime-backend-observation";
13
+ import { createSwiftLineClassifier } from "./swift-frame-parsing.js";
14
+ import { createSwiftSourceLocationResolver } from "./swift-source-location-resolver.js";
15
+ import { createSwiftStackTraceParser } from "./swift-stack-trace-parser.js";
16
+ export function createSwiftRuntimeAdapter(options = {}) {
17
+ const sourceLocationResolver = createSwiftSourceLocationResolver();
18
+ const stackTraceParser = createSwiftStackTraceParser(sourceLocationResolver);
19
+ function createBackendCollectors(sources) {
20
+ return sources.map((source) => createLogCollector({
21
+ source,
22
+ // One classifier per collector, never shared: it carries the
23
+ // "which bridging line are we expecting next" stage, and two
24
+ // processes' output must not prime each other.
25
+ classifier: createSwiftLineClassifier(),
26
+ stackTraceParser,
27
+ ...(options.service !== undefined ? { service: options.service } : {}),
28
+ }));
29
+ }
30
+ return {
31
+ language: "swift",
32
+ stackTraceParser,
33
+ sourceLocationResolver,
34
+ createBackendCollectors,
35
+ };
36
+ }
37
+ //# sourceMappingURL=swift-runtime-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-runtime-adapter.js","sourceRoot":"","sources":["../src/swift-runtime-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAO5E,MAAM,UAAU,yBAAyB,CAAC,UAAsC,EAAE;IAChF,MAAM,sBAAsB,GAAG,iCAAiC,EAAE,CAAC;IACnE,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,sBAAsB,CAAC,CAAC;IAE7E,SAAS,uBAAuB,CAAC,OAAuC;QACtE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAC5B,kBAAkB,CAAC;YACjB,MAAM;YACN,6DAA6D;YAC7D,6DAA6D;YAC7D,+CAA+C;YAC/C,UAAU,EAAE,yBAAyB,EAAE;YACvC,gBAAgB;YAChB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvE,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,gBAAgB;QAChB,sBAAsB;QACtB,uBAAuB;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Swift `SourceLocationResolver` — the second adapter in this codebase to
3
+ * use `side-artifact-resolved`/`-missing` (RT-041's C# was the first),
4
+ * and the same underlying reason: **resolving means reading a verdict the
5
+ * runtime already reached, not performing one.** The crash handler
6
+ * symbolicates each frame against the binary's own debug info (embedded
7
+ * DWARF on Linux, a paired `.dSYM` on Apple platforms) while building this
8
+ * text, before it is ever captured here — confirmed against
9
+ * `RuntimeErrorReporting.cpp`'s `dumpStackTraceEntry`, which looks the
10
+ * frame up and either finds a location or doesn't, before this adapter's
11
+ * code runs at all.
12
+ *
13
+ * - `file`/`line` present → debug info was available and matched →
14
+ * `side-artifact-resolved`.
15
+ * - `file`/`line` absent → no debug info was available for that image →
16
+ * `side-artifact-missing`, **not** `self-contained` — a compiled Swift
17
+ * frame always COULD have carried a location if debug info had been
18
+ * present for its image, unlike a language with no such mechanism at
19
+ * all. This is RT-041's own distinction (a managed C# frame vs. a PHP
20
+ * `[internal function]` frame), carried over rather than re-derived,
21
+ * because the underlying shape — a runtime that resolves against debug
22
+ * info before printing, rather than always capturing a location or
23
+ * never capturing one — is the same.
24
+ *
25
+ * **`side-artifact-stale` is not detected**, for the same reason as
26
+ * RT-041's C# resolver: verifying a `.dSYM`'s UUID against the running
27
+ * binary's `LC_UUID` load command (or comparing embedded DWARF checksums)
28
+ * is real, scoped work this adapter does not attempt without a `swift`
29
+ * toolchain to build and verify it against.
30
+ *
31
+ * **`resolvedVia` stays `null`.** The crash-handler text names the
32
+ * *image* a frame belongs to (`in libswiftCore.dylib`, `in InvoiceApp`)
33
+ * but never the specific `.dSYM` bundle or debug-info path that resolved
34
+ * it, so there is nothing to name without guessing one — the same
35
+ * reasoning as C#'s resolver, which cannot name a `.pdb` for the same
36
+ * kind of reason.
37
+ *
38
+ * `column` **is** populated, unlike every prior adapter's resolver in
39
+ * this codebase. Swift's `file:line:col` location is a real, captured
40
+ * fact — `RawFrameLocation.column` is passed straight through rather than
41
+ * discarded, because nothing here needs to derive or guess it the way a
42
+ * V8 source map's column sometimes does.
43
+ *
44
+ * **A `<compiler-generated>` pseudo-path (see `swift-frame-parsing.ts`
45
+ * point 3) reports `side-artifact-resolved`, not `-missing`**, even
46
+ * though `line`/`column` are null for it. The crash handler DID have
47
+ * enough information to name an origin for that frame — it simply isn't
48
+ * a source line — which is a different claim from "no debug info was
49
+ * available at all" and this resolver treats it that way rather than
50
+ * conflating the two.
51
+ */
52
+ import type { SourceLocationResolver } from "@descryy/runtime-backend-observation";
53
+ export declare function createSwiftSourceLocationResolver(): SourceLocationResolver;
54
+ //# sourceMappingURL=swift-source-location-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-source-location-resolver.d.ts","sourceRoot":"","sources":["../src/swift-source-location-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAGH,OAAO,KAAK,EAAoB,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAErG,wBAAgB,iCAAiC,IAAI,sBAAsB,CAgB1E"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Swift `SourceLocationResolver` — the second adapter in this codebase to
3
+ * use `side-artifact-resolved`/`-missing` (RT-041's C# was the first),
4
+ * and the same underlying reason: **resolving means reading a verdict the
5
+ * runtime already reached, not performing one.** The crash handler
6
+ * symbolicates each frame against the binary's own debug info (embedded
7
+ * DWARF on Linux, a paired `.dSYM` on Apple platforms) while building this
8
+ * text, before it is ever captured here — confirmed against
9
+ * `RuntimeErrorReporting.cpp`'s `dumpStackTraceEntry`, which looks the
10
+ * frame up and either finds a location or doesn't, before this adapter's
11
+ * code runs at all.
12
+ *
13
+ * - `file`/`line` present → debug info was available and matched →
14
+ * `side-artifact-resolved`.
15
+ * - `file`/`line` absent → no debug info was available for that image →
16
+ * `side-artifact-missing`, **not** `self-contained` — a compiled Swift
17
+ * frame always COULD have carried a location if debug info had been
18
+ * present for its image, unlike a language with no such mechanism at
19
+ * all. This is RT-041's own distinction (a managed C# frame vs. a PHP
20
+ * `[internal function]` frame), carried over rather than re-derived,
21
+ * because the underlying shape — a runtime that resolves against debug
22
+ * info before printing, rather than always capturing a location or
23
+ * never capturing one — is the same.
24
+ *
25
+ * **`side-artifact-stale` is not detected**, for the same reason as
26
+ * RT-041's C# resolver: verifying a `.dSYM`'s UUID against the running
27
+ * binary's `LC_UUID` load command (or comparing embedded DWARF checksums)
28
+ * is real, scoped work this adapter does not attempt without a `swift`
29
+ * toolchain to build and verify it against.
30
+ *
31
+ * **`resolvedVia` stays `null`.** The crash-handler text names the
32
+ * *image* a frame belongs to (`in libswiftCore.dylib`, `in InvoiceApp`)
33
+ * but never the specific `.dSYM` bundle or debug-info path that resolved
34
+ * it, so there is nothing to name without guessing one — the same
35
+ * reasoning as C#'s resolver, which cannot name a `.pdb` for the same
36
+ * kind of reason.
37
+ *
38
+ * `column` **is** populated, unlike every prior adapter's resolver in
39
+ * this codebase. Swift's `file:line:col` location is a real, captured
40
+ * fact — `RawFrameLocation.column` is passed straight through rather than
41
+ * discarded, because nothing here needs to derive or guess it the way a
42
+ * V8 source map's column sometimes does.
43
+ *
44
+ * **A `<compiler-generated>` pseudo-path (see `swift-frame-parsing.ts`
45
+ * point 3) reports `side-artifact-resolved`, not `-missing`**, even
46
+ * though `line`/`column` are null for it. The crash handler DID have
47
+ * enough information to name an origin for that frame — it simply isn't
48
+ * a source line — which is a different claim from "no debug info was
49
+ * available at all" and this resolver treats it that way rather than
50
+ * conflating the two.
51
+ */
52
+ export function createSwiftSourceLocationResolver() {
53
+ return {
54
+ // Async to satisfy the interface; there is no I/O to do here, since
55
+ // the crash handler already did (or didn't) resolve this frame before
56
+ // the text was captured.
57
+ resolve(frame) {
58
+ return Promise.resolve({
59
+ file: frame.file,
60
+ line: frame.line,
61
+ column: frame.column,
62
+ functionName: frame.functionName,
63
+ reliability: frame.file === null ? "side-artifact-missing" : "side-artifact-resolved",
64
+ resolvedVia: null,
65
+ });
66
+ },
67
+ };
68
+ }
69
+ //# sourceMappingURL=swift-source-location-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-source-location-resolver.js","sourceRoot":"","sources":["../src/swift-source-location-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAKH,MAAM,UAAU,iCAAiC;IAC/C,OAAO;QACL,oEAAoE;QACpE,sEAAsE;QACtE,yBAAyB;QACzB,OAAO,CAAC,KAAuB;YAC7B,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,WAAW,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,wBAAwB;gBACrF,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Composes the pure Swift line-recognition functions
3
+ * (`swift-frame-parsing.ts`) with a `SourceLocationResolver` to implement
4
+ * the full async `StackTraceParser` contract.
5
+ *
6
+ * **No reversal.** The cited `FileCheck` test numbers frame 0 as the trap
7
+ * site itself (`_assertionFailure`) and counts upward to `main` — most-
8
+ * recent-first already, the same convention as V8, the JVM, Go, Rust and
9
+ * C#; CPython remains the only reversing outlier in this codebase.
10
+ *
11
+ * `fidelity` is always reported `"synchronous"`. The crash-handler walks
12
+ * the actual thread that trapped; it cannot show a logical caller across
13
+ * a Swift `Task`/actor hop the runtime itself didn't preserve, the same
14
+ * hard limit every other adapter in this codebase shares. Claiming
15
+ * `"concurrency-fragmented"` without an explicit marker for it would be a
16
+ * guess this project refuses to make.
17
+ *
18
+ * ## Two things a real Swift crash added that the transcript could not
19
+ *
20
+ * Both measured against Swift 6.1.2 on Linux (RT-122), and neither is
21
+ * visible in a single-threaded fixture:
22
+ *
23
+ * **1. Only the thread marked `crashed:` becomes frames.** When the trap
24
+ * happens off the main thread, Swift dumps *every* thread, and the
25
+ * uncrashed ones are printed **first**:
26
+ *
27
+ * ```
28
+ * Thread 0 "server": <- still sitting in accept(); did not crash
29
+ * 0 … accept + 77 in libc.so.6
30
+ * …
31
+ * Thread 1 crashed: <- the one that trapped
32
+ * 0 … _assertionFailure … in libswiftCore.so
33
+ * 4 … readCustomerName(_:) … at …/server.swift:10:28
34
+ * ```
35
+ *
36
+ * Reading every frame-shaped line, as this parser used to, concatenates
37
+ * two unrelated call chains into one — the identical fabricated-call-
38
+ * relationship error `adapter-go` refuses for goroutines — and, worse,
39
+ * puts a thread that did not crash at the head of the list, so
40
+ * `Evidence.sourceLocation` names `accept` in libc. The other threads stay
41
+ * in the block's raw text, disclosed rather than merged or discarded.
42
+ *
43
+ * **2. `primaryFrameIndex` points at the position the header declares.**
44
+ * Swift's `Fatal error:` line on Linux carries one —
45
+ * `server/server.swift:10: Fatal error: …` — and frames 0..3 above the
46
+ * application frame are `_assertionFailure` closures inside
47
+ * `libswiftCore.so`. `collector.ts` reports `frames[0]` as
48
+ * `Evidence.sourceLocation`, so unrooted this names a Swift-runtime
49
+ * closure with no source location at all.
50
+ *
51
+ * This is an exact join on a position the runtime printed, not a
52
+ * classification of images as "runtime" or "application": nothing here
53
+ * looks at `libswiftCore.so`. It matches on **basename and line** — the
54
+ * header's `#file` is `Module/File.swift` while a frame carries the
55
+ * absolute path, so neither is a prefix of the other, and Swift's header
56
+ * (unlike Rust's) has no column to tighten it with. That is a weaker join
57
+ * than Rust's and is stated as such. The transcribed fixtures declare no
58
+ * position at all, so the index stays `0` for them — the honest outcome,
59
+ * not a fallback.
60
+ *
61
+ * ## An unsymbolicated dump is a stack, not the absence of one (RT-126/128)
62
+ *
63
+ * When the backtracer cannot symbolicate it still unwinds correctly and
64
+ * prints every frame as a bare address. Those frames are parsed and kept,
65
+ * with `file`, `line`, `functionName` and `column` all null and the address
66
+ * preserved in `StackFrame.raw`. `fidelity` stays `"synchronous"` — the
67
+ * chain is entirely accurate, only its names are missing, and
68
+ * `"unavailable"` describes a different axis (whether the stack reflects
69
+ * the logical call chain) that this does not touch.
70
+ *
71
+ * The alternative — returning `null`, as this parser did — made "a Swift
72
+ * crash we could not name" indistinguishable from "not a Swift crash",
73
+ * which is the disclosure failure §38 exists to ban. `primaryFrameIndex`
74
+ * stays `0`: no rooting is possible without names, and Lane A's
75
+ * `primaryFrameLocation` (RT-087) turns that frame into a null
76
+ * `Evidence.sourceLocation` rather than a location naming nothing.
77
+ *
78
+ * **Selecting a thread is not the same as choosing an index, and only one
79
+ * of the two became a view.** `primaryFrameIndex` (RT-083) keeps every
80
+ * frame of the crashed thread and points at the failure site. The
81
+ * *uncrashed* threads are still excluded from `frames` entirely, because
82
+ * they are not frames of this stack at all — including them would assert a
83
+ * call relationship between independent threads, which no index can undo.
84
+ * They remain in `payload.raw`.
85
+ */
86
+ import type { SourceLocationResolver, StackTraceParser } from "@descryy/runtime-backend-observation";
87
+ export declare function createSwiftStackTraceParser(resolver: SourceLocationResolver): StackTraceParser;
88
+ //# sourceMappingURL=swift-stack-trace-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-stack-trace-parser.d.ts","sourceRoot":"","sources":["../src/swift-stack-trace-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAmCrG,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,CA+C9F"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Composes the pure Swift line-recognition functions
3
+ * (`swift-frame-parsing.ts`) with a `SourceLocationResolver` to implement
4
+ * the full async `StackTraceParser` contract.
5
+ *
6
+ * **No reversal.** The cited `FileCheck` test numbers frame 0 as the trap
7
+ * site itself (`_assertionFailure`) and counts upward to `main` — most-
8
+ * recent-first already, the same convention as V8, the JVM, Go, Rust and
9
+ * C#; CPython remains the only reversing outlier in this codebase.
10
+ *
11
+ * `fidelity` is always reported `"synchronous"`. The crash-handler walks
12
+ * the actual thread that trapped; it cannot show a logical caller across
13
+ * a Swift `Task`/actor hop the runtime itself didn't preserve, the same
14
+ * hard limit every other adapter in this codebase shares. Claiming
15
+ * `"concurrency-fragmented"` without an explicit marker for it would be a
16
+ * guess this project refuses to make.
17
+ *
18
+ * ## Two things a real Swift crash added that the transcript could not
19
+ *
20
+ * Both measured against Swift 6.1.2 on Linux (RT-122), and neither is
21
+ * visible in a single-threaded fixture:
22
+ *
23
+ * **1. Only the thread marked `crashed:` becomes frames.** When the trap
24
+ * happens off the main thread, Swift dumps *every* thread, and the
25
+ * uncrashed ones are printed **first**:
26
+ *
27
+ * ```
28
+ * Thread 0 "server": <- still sitting in accept(); did not crash
29
+ * 0 … accept + 77 in libc.so.6
30
+ * …
31
+ * Thread 1 crashed: <- the one that trapped
32
+ * 0 … _assertionFailure … in libswiftCore.so
33
+ * 4 … readCustomerName(_:) … at …/server.swift:10:28
34
+ * ```
35
+ *
36
+ * Reading every frame-shaped line, as this parser used to, concatenates
37
+ * two unrelated call chains into one — the identical fabricated-call-
38
+ * relationship error `adapter-go` refuses for goroutines — and, worse,
39
+ * puts a thread that did not crash at the head of the list, so
40
+ * `Evidence.sourceLocation` names `accept` in libc. The other threads stay
41
+ * in the block's raw text, disclosed rather than merged or discarded.
42
+ *
43
+ * **2. `primaryFrameIndex` points at the position the header declares.**
44
+ * Swift's `Fatal error:` line on Linux carries one —
45
+ * `server/server.swift:10: Fatal error: …` — and frames 0..3 above the
46
+ * application frame are `_assertionFailure` closures inside
47
+ * `libswiftCore.so`. `collector.ts` reports `frames[0]` as
48
+ * `Evidence.sourceLocation`, so unrooted this names a Swift-runtime
49
+ * closure with no source location at all.
50
+ *
51
+ * This is an exact join on a position the runtime printed, not a
52
+ * classification of images as "runtime" or "application": nothing here
53
+ * looks at `libswiftCore.so`. It matches on **basename and line** — the
54
+ * header's `#file` is `Module/File.swift` while a frame carries the
55
+ * absolute path, so neither is a prefix of the other, and Swift's header
56
+ * (unlike Rust's) has no column to tighten it with. That is a weaker join
57
+ * than Rust's and is stated as such. The transcribed fixtures declare no
58
+ * position at all, so the index stays `0` for them — the honest outcome,
59
+ * not a fallback.
60
+ *
61
+ * ## An unsymbolicated dump is a stack, not the absence of one (RT-126/128)
62
+ *
63
+ * When the backtracer cannot symbolicate it still unwinds correctly and
64
+ * prints every frame as a bare address. Those frames are parsed and kept,
65
+ * with `file`, `line`, `functionName` and `column` all null and the address
66
+ * preserved in `StackFrame.raw`. `fidelity` stays `"synchronous"` — the
67
+ * chain is entirely accurate, only its names are missing, and
68
+ * `"unavailable"` describes a different axis (whether the stack reflects
69
+ * the logical call chain) that this does not touch.
70
+ *
71
+ * The alternative — returning `null`, as this parser did — made "a Swift
72
+ * crash we could not name" indistinguishable from "not a Swift crash",
73
+ * which is the disclosure failure §38 exists to ban. `primaryFrameIndex`
74
+ * stays `0`: no rooting is possible without names, and Lane A's
75
+ * `primaryFrameLocation` (RT-087) turns that frame into a null
76
+ * `Evidence.sourceLocation` rather than a location naming nothing.
77
+ *
78
+ * **Selecting a thread is not the same as choosing an index, and only one
79
+ * of the two became a view.** `primaryFrameIndex` (RT-083) keeps every
80
+ * frame of the crashed thread and points at the failure site. The
81
+ * *uncrashed* threads are still excluded from `frames` entirely, because
82
+ * they are not frames of this stack at all — including them would assert a
83
+ * call relationship between independent threads, which no index can undo.
84
+ * They remain in `payload.raw`.
85
+ */
86
+ import { isSwiftCrashedThreadLine, isSwiftThreadLine, parseSwiftFrame, parseSwiftHeaderPosition, } from "./swift-frame-parsing.js";
87
+ const basename = (path) => path.split("/").pop() ?? path;
88
+ /**
89
+ * The lines belonging to the thread that actually trapped.
90
+ *
91
+ * A dump with no thread headers at all (the transcribed fixtures) is one
92
+ * implicit block and every line is returned. A dump with thread headers
93
+ * but none marked `crashed` is refused a choice: every line is returned,
94
+ * which keeps the pre-existing behaviour rather than picking a thread on
95
+ * no evidence. Swift has always marked one in every shape observed, so
96
+ * that branch is a guard, not a supported case.
97
+ */
98
+ function crashedThreadLines(lines) {
99
+ const start = lines.findIndex(isSwiftCrashedThreadLine);
100
+ if (start === -1)
101
+ return lines;
102
+ let end = lines.length;
103
+ for (let i = start + 1; i < lines.length; i++) {
104
+ if (isSwiftThreadLine(lines[i])) {
105
+ end = i;
106
+ break;
107
+ }
108
+ }
109
+ return lines.slice(start + 1, end);
110
+ }
111
+ export function createSwiftStackTraceParser(resolver) {
112
+ return {
113
+ async parse(rawText) {
114
+ const lines = rawText.split(/\r\n|\r|\n/);
115
+ const declared = lines.map(parseSwiftHeaderPosition).find((p) => p !== null) ?? null;
116
+ const frames = [];
117
+ /** Index of the frame at the header's own declared position, or -1 when nothing declares or matches one — reported as `primaryFrameIndex: 0`, stated rather than defaulted. */
118
+ let declaredSite = -1;
119
+ for (const line of crashedThreadLines(lines)) {
120
+ // The header and the bridging lines all parse to null here — real
121
+ // parts of the block, none fabricated into a frame.
122
+ const raw = parseSwiftFrame(line);
123
+ if (raw === null)
124
+ continue;
125
+ const location = await resolver.resolve({
126
+ file: raw.file,
127
+ line: raw.line,
128
+ column: raw.column,
129
+ functionName: raw.functionName,
130
+ });
131
+ frames.push({ location, raw: line });
132
+ // First match only: recursion would repeat the position further
133
+ // down, and the outermost repetition is not where execution was.
134
+ if (declaredSite === -1 &&
135
+ declared !== null &&
136
+ raw.file !== null &&
137
+ raw.line === declared.line &&
138
+ basename(raw.file) === basename(declared.file)) {
139
+ declaredSite = frames.length - 1;
140
+ }
141
+ }
142
+ if (frames.length === 0) {
143
+ // Nothing frame-shaped at all — not recognisable as a Swift crash
144
+ // trace, per this interface's contract: null, never an empty-but-
145
+ // structured StackTrace standing in for "couldn't parse".
146
+ return null;
147
+ }
148
+ return { fidelity: "synchronous", frames, primaryFrameIndex: declaredSite > 0 ? declaredSite : 0 };
149
+ },
150
+ };
151
+ }
152
+ //# sourceMappingURL=swift-stack-trace-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-stack-trace-parser.js","sourceRoot":"","sources":["../src/swift-stack-trace-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AAKH,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EACf,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;AAEzE;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CAAC,KAAwB;IAClD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACxD,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/B,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YACjC,GAAG,GAAG,CAAC,CAAC;YACR,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,QAAgC;IAC1E,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,OAAe;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;YAErF,MAAM,MAAM,GAAiB,EAAE,CAAC;YAChC,+KAA+K;YAC/K,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;YAEtB,KAAK,MAAM,IAAI,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7C,kEAAkE;gBAClE,oDAAoD;gBACpD,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;gBAClC,IAAI,GAAG,KAAK,IAAI;oBAAE,SAAS;gBAE3B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC;oBACtC,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,YAAY,EAAE,GAAG,CAAC,YAAY;iBAC/B,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;gBAErC,gEAAgE;gBAChE,iEAAiE;gBACjE,IACE,YAAY,KAAK,CAAC,CAAC;oBACnB,QAAQ,KAAK,IAAI;oBACjB,GAAG,CAAC,IAAI,KAAK,IAAI;oBACjB,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;oBAC1B,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC9C,CAAC;oBACD,YAAY,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,kEAAkE;gBAClE,kEAAkE;gBAClE,0DAA0D;gBAC1D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrG,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@descryy/runtime-adapter-swift",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "description": "Swift runtime adapter: crash-handler trace parsing, side-artifact-aware source locations, the concrete RuntimeAdapter for Swift.",
6
+ "license": "UNLICENSED",
7
+ "engines": {
8
+ "node": ">=22.5"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "publishConfig": {
20
+ "registry": "https://registry.npmjs.org",
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc -b"
25
+ },
26
+ "dependencies": {
27
+ "@descryy/runtime-contracts": "*",
28
+ "@descryy/runtime-backend-observation": "*"
29
+ }
30
+ }