Skip to content

Commit 43ac069

Browse files
committed
[Backtracing] Add control over symbol caching.
Some symbolication frameworks have a symbol cache; we probably don't want to use that for test cases, to avoid running into problems where the cache holds stale information. rdar://105409147
1 parent 662c80e commit 43ac069

File tree

15 files changed

+198
-159
lines changed

15 files changed

+198
-159
lines changed

docs/Backtracing.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ follows:
9292
| top | 16 | Specify a minimum number of frames to capture |
9393
| | | from the top of the stack. See below for more. |
9494
+-----------------+---------+--------------------------------------------------+
95+
| cache | yes | Set to ``no`` to disable symbol caching. This |
96+
| | | only has effect on platforms that have a symbol |
97+
| | | cache that can be controlled by the runtime. |
98+
+-----------------+---------+--------------------------------------------------+
9599
| swift-backtrace | | If specified, gives the full path to the |
96100
| | | swift-backtrace binary to use for crashes. |
97101
| | | Otherwise, Swift will locate the binary relative |

include/swift/Runtime/Backtrace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct BacktraceSettings {
111111
unsigned top;
112112
SanitizePaths sanitize;
113113
Preset preset;
114+
bool cache;
114115
const char *swiftBacktracePath;
115116
};
116117

stdlib/public/Backtracing/Backtrace.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,20 @@ public struct Backtrace: CustomStringConvertible, Sendable {
444444
/// running on, add virtual frames to show inline
445445
/// function calls.
446446
///
447+
/// @param useSymbolCache If the system we are on has a symbol cache,
448+
/// says whether or not to use it.
449+
///
447450
/// @returns A new `SymbolicatedBacktrace`.
448451
public func symbolicated(with images: [Image]? = nil,
449452
sharedCacheInfo: SharedCacheInfo? = nil,
450-
showInlineFrames: Bool = true)
453+
showInlineFrames: Bool = true,
454+
useSymbolCache: Bool = true)
451455
-> SymbolicatedBacktrace? {
452456
return SymbolicatedBacktrace.symbolicate(backtrace: self,
453457
images: images,
454458
sharedCacheInfo: sharedCacheInfo,
455-
showInlineFrames: showInlineFrames)
459+
showInlineFrames: showInlineFrames,
460+
useSymbolCache: useSymbolCache)
456461
}
457462

458463
/// Provide a textual version of the backtrace.

stdlib/public/Backtracing/CoreSymbolication.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ func CSIsNull(_ obj: CSTypeRef) -> Bool {
186186

187187
// .. CSSymbolicator ...........................................................
188188

189+
let kCSSymbolicatorDisallowDaemonCommunication = UInt32(0x00000800)
189190

190191
struct BinaryRelocationInformation {
191192
var base: mach_vm_address_t

stdlib/public/Backtracing/SymbolicatedBacktrace.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ public struct SymbolicatedBacktrace: CustomStringConvertible {
259259
/// Create a symbolicator.
260260
private static func withSymbolicator<T>(images: [Backtrace.Image],
261261
sharedCacheInfo: Backtrace.SharedCacheInfo?,
262+
useSymbolCache: Bool,
262263
fn: (CSSymbolicatorRef) throws -> T) rethrows -> T {
263264
let binaryImageList = images.map{ image in
264265
BinaryImageInformation(
@@ -279,7 +280,9 @@ public struct SymbolicatedBacktrace: CustomStringConvertible {
279280
}
280281

281282
let symbolicator = CSSymbolicatorCreateWithBinaryImageList(
282-
binaryImageList, 0, nil
283+
binaryImageList,
284+
useSymbolCache ? 0 : kCSSymbolicatorDisallowDaemonCommunication,
285+
nil
283286
)
284287

285288
defer { CSRelease(symbolicator) }
@@ -345,7 +348,8 @@ public struct SymbolicatedBacktrace: CustomStringConvertible {
345348
internal static func symbolicate(backtrace: Backtrace,
346349
images: [Backtrace.Image]?,
347350
sharedCacheInfo: Backtrace.SharedCacheInfo?,
348-
showInlineFrames: Bool)
351+
showInlineFrames: Bool,
352+
useSymbolCache: Bool)
349353
-> SymbolicatedBacktrace? {
350354

351355
let theImages: [Backtrace.Image]
@@ -370,7 +374,8 @@ public struct SymbolicatedBacktrace: CustomStringConvertible {
370374

371375
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
372376
withSymbolicator(images: theImages,
373-
sharedCacheInfo: theCacheInfo) { symbolicator in
377+
sharedCacheInfo: theCacheInfo,
378+
useSymbolCache: useSymbolCache) { symbolicator in
374379
for frame in backtrace.frames {
375380
switch frame {
376381
case .omittedFrames(_), .truncated:

stdlib/public/libexec/swift-backtrace/Target.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class Target {
141141
}
142142
}
143143

144-
init(crashInfoAddr: UInt64, limit: Int?, top: Int) {
144+
init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool) {
145145
pid = getppid()
146146
if let parentTask = Self.getParentTask() {
147147
task = parentTask
@@ -177,10 +177,10 @@ class Target {
177177
images = Backtrace.captureImages(for: task)
178178
sharedCacheInfo = Backtrace.captureSharedCacheInfo(for: task)
179179

180-
fetchThreads(limit: limit, top: top)
180+
fetchThreads(limit: limit, top: top, cache: cache)
181181
}
182182

183-
func fetchThreads(limit: Int?, top: Int) {
183+
func fetchThreads(limit: Int?, top: Int, cache: Bool) {
184184
var threadPorts: thread_act_array_t? = nil
185185
var threadCount: mach_msg_type_number_t = 0
186186
let kr = task_threads(task,
@@ -248,7 +248,8 @@ class Target {
248248
}
249249

250250
guard let symbolicated = backtrace.symbolicated(with: images,
251-
sharedCacheInfo: sharedCacheInfo) else {
251+
sharedCacheInfo: sharedCacheInfo,
252+
useSymbolCache: cache) else {
252253
print("unable to symbolicate backtrace from context for thread \(ndx)")
253254
exit(1)
254255
}
@@ -262,7 +263,7 @@ class Target {
262263
}
263264
}
264265

265-
public func redoBacktraces(limit: Int?, top: Int) {
266+
public func redoBacktraces(limit: Int?, top: Int, cache: Bool) {
266267
for (ndx, thread) in threads.enumerated() {
267268
guard let context = thread.context else {
268269
continue
@@ -277,7 +278,8 @@ class Target {
277278
}
278279

279280
guard let symbolicated = backtrace.symbolicated(with: images,
280-
sharedCacheInfo: sharedCacheInfo) else {
281+
sharedCacheInfo: sharedCacheInfo,
282+
useSymbolCache: cache) else {
281283
print("unable to symbolicate backtrace from context for thread \(ndx)")
282284
continue
283285
}

stdlib/public/libexec/swift-backtrace/main.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ internal struct SwiftBacktrace {
6565
var limit: Int? = 64
6666
var top = 16
6767
var sanitize: Bool? = nil
68+
var cache = true
6869
}
6970

7071
static var args = Arguments()
@@ -83,7 +84,7 @@ internal struct SwiftBacktrace {
8384

8485
static func usage() {
8586
print("""
86-
usage: swift-backtrace [--unwind <algorithm>] [--demangle [<bool>]] [--interactive [<bool>]] [--color [<bool>]] [--timeout <seconds>] [--preset <preset>] [--threads [<bool>]] [--registers <registers>] [--images <images>] --crashinfo <addr>
87+
usage: swift-backtrace [--unwind <algorithm>] [--demangle [<bool>]] [--interactive [<bool>]] [--color [<bool>]] [--timeout <seconds>] [--preset <preset>] [--threads [<bool>]] [--registers <registers>] [--images <images>] [--cache [<bool>]] --crashinfo <addr>
8788
8889
Generate a backtrace for the parent process.
8990
@@ -130,6 +131,8 @@ Generate a backtrace for the parent process.
130131
--sanitize [<bool>]
131132
-s [<bool>] Set whether or not to sanitize paths.
132133
134+
--cache [<bool>] Set whether or not to use the symbol cache, if any.
135+
133136
--crashinfo <addr>
134137
-a <addr> Provide a pointer to a platform specific CrashInfo
135138
structure. <addr> should be in hexadecimal.
@@ -295,6 +298,12 @@ Generate a backtrace for the parent process.
295298
} else {
296299
args.sanitize = true
297300
}
301+
case "--cache":
302+
if let v = value {
303+
args.cache = parseBool(v)
304+
} else {
305+
args.cache = true
306+
}
298307
case "-a", "--crashinfo":
299308
if let v = value {
300309
if let a = UInt64(v, radix: 16) {
@@ -381,7 +390,8 @@ Generate a backtrace for the parent process.
381390
formattingOptions = formattingOptions.showImages(.none)
382391

383392
target = Target(crashInfoAddr: crashInfoAddr,
384-
limit: args.limit, top: args.top)
393+
limit: args.limit, top: args.top,
394+
cache: args.cache)
385395

386396
currentThread = target!.crashingThreadNdx
387397

@@ -903,7 +913,9 @@ Generate a backtrace for the parent process.
903913
}
904914

905915
if changedBacktrace {
906-
target.redoBacktraces(limit: args.limit, top: args.top)
916+
target.redoBacktraces(limit: args.limit,
917+
top: args.top,
918+
cache: args.cache)
907919
}
908920
}
909921
}

stdlib/public/runtime/Backtrace.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ SWIFT_RUNTIME_STDLIB_INTERNAL BacktraceSettings _swift_backtraceSettings = {
104104
// preset
105105
Preset::Auto,
106106

107+
// cache
108+
true,
109+
107110
// swiftBacktracePath
108111
NULL,
109112
};
@@ -599,6 +602,8 @@ _swift_processBacktracingSetting(llvm::StringRef key,
599602
"swift runtime: bad backtrace top count '%.*s'\n",
600603
static_cast<int>(value.size()), value.data());
601604
}
605+
} else if (key.equals_insensitive("cache")) {
606+
_swift_backtraceSettings.cache = parseBoolean(value);
602607
} else if (key.equals_insensitive("swift-backtrace")) {
603608
size_t len = value.size();
604609
char *path = (char *)std::malloc(len + 1);

stdlib/public/runtime/CrashHandlerMacOS.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ const char *backtracer_argv[] = {
268268
top_buf, // 24
269269
"--sanitize", // 25
270270
"preset", // 26
271+
"--cache", // 27
272+
"true", // 28
271273
NULL
272274
};
273275

@@ -440,6 +442,8 @@ run_backtracer()
440442
break;
441443
}
442444

445+
backtracer_argv[28] = trueOrFalse(_swift_backtraceSettings.cache);
446+
443447
format_unsigned(_swift_backtraceSettings.timeout, timeout_buf);
444448

445449
if (_swift_backtraceSettings.limit < 0)

test/Backtracing/Crash.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
// RUN: %target-codesign %t/CrashNoDebug
88
// RUN: %target-codesign %t/CrashOpt
99
// RUN: %target-codesign %t/CrashOptNoDebug
10-
// RUN: (env SWIFT_BACKTRACE=enable=yes %target-run %t/Crash || true) | %FileCheck %s
11-
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes %target-run %t/Crash || true) | %FileCheck %s --check-prefix FRIENDLY
12-
// RUN: (env SWIFT_BACKTRACE=enable=yes %target-run %t/CrashNoDebug || true) | %FileCheck %s --check-prefix NODEBUG
13-
// RUN: (env SWIFT_BACKTRACE=enable=yes %target-run %t/CrashOpt || true) | %FileCheck %s --check-prefix OPTIMIZED
14-
// RUN: (env SWIFT_BACKTRACE=enable=yes %target-run %t/CrashOptNoDebug || true) | %FileCheck %s --check-prefix OPTNODEBUG
10+
// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no %target-run %t/Crash || true) | %FileCheck %s
11+
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes,cache=no %target-run %t/Crash || true) | %FileCheck %s --check-prefix FRIENDLY
12+
// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no %target-run %t/CrashNoDebug || true) | %FileCheck %s --check-prefix NODEBUG
13+
// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no %target-run %t/CrashOpt || true) | %FileCheck %s --check-prefix OPTIMIZED
14+
// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no %target-run %t/CrashOptNoDebug || true) | %FileCheck %s --check-prefix OPTNODEBUG
1515

1616
// REQUIRES: executable_test
1717
// REQUIRES: OS=macosx

test/Backtracing/CrashWithThunk.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-build-swift %s -parse-as-library -Onone -g -o %t/CrashWithThunk
33
// RUN: %target-codesign %t/CrashWithThunk
4-
// RUN: (env SWIFT_BACKTRACE=enable=yes %target-run %t/CrashWithThunk || true) | %FileCheck %s
5-
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes %target-run %t/CrashWithThunk || true) | %FileCheck %s --check-prefix FRIENDLY
4+
// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no %target-run %t/CrashWithThunk || true) | %FileCheck %s
5+
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes,cache=no %target-run %t/CrashWithThunk || true) | %FileCheck %s --check-prefix FRIENDLY
66

77
// REQUIRES: executable_test
88
// REQUIRES: OS=macosx

test/Backtracing/Overflow.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-build-swift %s -parse-as-library -Onone -g -o %t/Overflow
33
// RUN: %target-codesign %t/Overflow
4-
// RUN: (env SWIFT_BACKTRACE=enable=yes %target-run %t/Overflow || true) | %FileCheck %s
5-
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes %target-run %t/Overflow || true) | %FileCheck %s --check-prefix FRIENDLY
4+
// RUN: (env SWIFT_BACKTRACE=enable=yes,cache=no %target-run %t/Overflow || true) | %FileCheck %s
5+
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes,cache=no %target-run %t/Overflow || true) | %FileCheck %s --check-prefix FRIENDLY
66

77
// REQUIRES: executable_test
88
// REQUIRES: OS=macosx
@@ -42,11 +42,11 @@ struct Overflow {
4242
// CHECK: Thread 0 crashed:
4343

4444
// CHECK: 0 [inlined] [system] 0x{{[0-9a-f]+}} Swift runtime failure: arithmetic overflow in Overflow at {{.*}}/<compiler-generated>
45-
// CHECK-NEXT: 1 0x{{[0-9a-f]+}} level5() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:{{30|29}}:5
46-
// CHECK-NEXT: 2 [ra] 0x{{[0-9a-f]+}} level4() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:{{24|23}}:3
47-
// CHECK-NEXT: 3 [ra] 0x{{[0-9a-f]+}} level3() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:{{20|19}}:3
48-
// CHECK-NEXT: 4 [ra] 0x{{[0-9a-f]+}} level2() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:{{16|15}}:3
49-
// CHECK-NEXT: 5 [ra] 0x{{[0-9a-f]+}} level1() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:{{12|11}}:3
45+
// CHECK-NEXT: 1 0x{{[0-9a-f]+}} level5() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:30:5
46+
// CHECK-NEXT: 2 [ra] 0x{{[0-9a-f]+}} level4() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:24:3
47+
// CHECK-NEXT: 3 [ra] 0x{{[0-9a-f]+}} level3() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:20:3
48+
// CHECK-NEXT: 4 [ra] 0x{{[0-9a-f]+}} level2() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:16:3
49+
// CHECK-NEXT: 5 [ra] 0x{{[0-9a-f]+}} level1() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:12:3
5050
// CHECK-NEXT: 6 [ra] 0x{{[0-9a-f]+}} static Overflow.main() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:36:5
5151
// CHECK-NEXT: 7 [ra] [system] 0x{{[0-9a-f]+}} static Overflow.$main() + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift:33:1
5252
// CHECK-NEXT: 8 [ra] [system] 0x{{[0-9a-f]+}} main + {{[0-9]+}} in Overflow at {{.*}}/Overflow.swift

0 commit comments

Comments
 (0)