Skip to content

Commit ed9f7ac

Browse files
committed
[Runtime] Add an option to produce non-symbolicated backtraces.
Symbolication can take some time, depending on the binaries involved. In certain contexts it's better for the backtrace to finish quickly, and then symbolication could be done offline. rdar://122302117
1 parent 63c8b55 commit ed9f7ac

File tree

8 files changed

+226
-92
lines changed

8 files changed

+226
-92
lines changed

stdlib/public/Backtracing/BacktraceFormatter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,12 +545,12 @@ public struct BacktraceFormatter {
545545
if let index = index {
546546
columns.append(options._theme.frameIndex("\(index)"))
547547
}
548-
columns.append(options._theme.programCounter(pc))
549548
if options._showFrameAttributes {
550549
columns.append(attrs.map(
551550
options._theme.frameAttribute
552551
).joined(separator: " "))
553552
}
553+
columns.append(options._theme.programCounter(pc))
554554

555555
return columns
556556
}

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

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,18 @@ import _Backtracing
2727

2828
@_implementationOnly import Runtime
2929

30+
enum SomeBacktrace {
31+
case raw(Backtrace)
32+
case symbolicated(SymbolicatedBacktrace)
33+
}
34+
3035
struct TargetThread {
3136
typealias ThreadID = pid_t
3237

3338
var id: ThreadID
3439
var context: HostContext?
3540
var name: String
36-
var backtrace: SymbolicatedBacktrace
41+
var backtrace: SomeBacktrace
3742
}
3843

3944
class Target {
@@ -105,7 +110,8 @@ class Target {
105110
return trimmed
106111
}
107112

108-
init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool) {
113+
init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool,
114+
symbolicate: Bool) {
109115
// fd #4 is reserved for the memory server
110116
let memserverFd: CInt = 4
111117

@@ -130,7 +136,8 @@ class Target {
130136

131137
do {
132138
try fetchThreads(threadListHead: Address(crashInfo.thread_list),
133-
limit: limit, top: top, cache: cache)
139+
limit: limit, top: top, cache: cache,
140+
symbolicate: symbolicate)
134141
} catch {
135142
print("swift-backtrace: failed to fetch thread information: \(error)")
136143
exit(1)
@@ -143,7 +150,7 @@ class Target {
143150
/// uninterruptible wait, we won't have a ucontext for it.
144151
func fetchThreads(
145152
threadListHead: Address,
146-
limit: Int?, top: Int, cache: Bool
153+
limit: Int?, top: Int, cache: Bool, symbolicate: Bool
147154
) throws {
148155
var next = threadListHead
149156

@@ -164,18 +171,26 @@ class Target {
164171
images: images,
165172
limit: limit,
166173
top: top)
167-
guard let symbolicated
168-
= backtrace.symbolicated(with: images,
169-
sharedCacheInfo: nil,
170-
useSymbolCache: cache) else {
171-
print("unable to symbolicate backtrace for thread \(t.tid)")
172-
exit(1)
173-
}
174174

175-
threads.append(TargetThread(id: TargetThread.ThreadID(t.tid),
176-
context: context,
177-
name: getThreadName(tid: t.tid),
178-
backtrace: symbolicated))
175+
if symbolicate {
176+
guard let symbolicated
177+
= backtrace.symbolicated(with: images,
178+
sharedCacheInfo: nil,
179+
useSymbolCache: cache) else {
180+
print("unable to symbolicate backtrace for thread \(t.tid)")
181+
exit(1)
182+
}
183+
184+
threads.append(TargetThread(id: TargetThread.ThreadID(t.tid),
185+
context: context,
186+
name: getThreadName(tid: t.tid),
187+
backtrace: .symbolicated(symbolicated)))
188+
} else {
189+
threads.append(TargetThread(id: TargetThread.ThreadID(t.tid),
190+
context: context,
191+
name: getThreadName(tid: t.tid),
192+
backtrace: .raw(backtrace)))
193+
}
179194
}
180195

181196
// Sort the threads by thread ID; the main thread always sorts
@@ -193,7 +208,7 @@ class Target {
193208
}
194209
}
195210

196-
func redoBacktraces(limit: Int?, top: Int, cache: Bool) {
211+
func redoBacktraces(limit: Int?, top: Int, cache: Bool, symbolicate: Bool) {
197212
for (ndx, thread) in threads.enumerated() {
198213
guard let context = thread.context else {
199214
continue
@@ -208,14 +223,18 @@ class Target {
208223
continue
209224
}
210225

211-
guard let symbolicated = backtrace.symbolicated(with: images,
212-
sharedCacheInfo: nil,
213-
useSymbolCache: cache) else {
214-
print("unable to symbolicate backtrace from context for thread \(ndx)")
215-
continue
226+
if symbolicate {
227+
guard let symbolicated = backtrace.symbolicated(with: images,
228+
sharedCacheInfo: nil,
229+
useSymbolCache: cache) else {
230+
print("unable to symbolicate backtrace from context for thread \(ndx)")
231+
continue
232+
}
233+
234+
threads[ndx].backtrace = .symbolicated(symbolicated)
235+
} else {
236+
threads[ndx].backtrace = .raw(backtrace)
216237
}
217-
218-
threads[ndx].backtrace = symbolicated
219238
}
220239
}
221240

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

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,18 @@ extension thread_extended_info {
4646
}
4747
}
4848

49+
enum SomeBacktrace {
50+
case raw(Backtrace)
51+
case symbolicated(SymbolicatedBacktrace)
52+
}
53+
4954
struct TargetThread {
5055
typealias ThreadID = UInt64
5156

5257
var id: ThreadID
5358
var context: HostContext?
5459
var name: String
55-
var backtrace: SymbolicatedBacktrace
60+
var backtrace: SomeBacktrace
5661
}
5762

5863
class Target {
@@ -134,7 +139,8 @@ class Target {
134139
(flags & UInt32(CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != 0
135140
}
136141

137-
init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool) {
142+
init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool,
143+
symbolicate: Bool) {
138144
pid = getppid()
139145

140146
if Self.isPlatformBinary(pid: pid) {
@@ -185,10 +191,10 @@ class Target {
185191
images = Backtrace.captureImages(for: task)
186192
sharedCacheInfo = Backtrace.captureSharedCacheInfo(for: task)
187193

188-
fetchThreads(limit: limit, top: top, cache: cache)
194+
fetchThreads(limit: limit, top: top, cache: cache, symbolicate: symbolicate)
189195
}
190196

191-
func fetchThreads(limit: Int?, top: Int, cache: Bool) {
197+
func fetchThreads(limit: Int?, top: Int, cache: Bool, symbolicate: Bool) {
192198
var threadPorts: thread_act_array_t? = nil
193199
var threadCount: mach_msg_type_number_t = 0
194200
let kr = task_threads(task,
@@ -260,24 +266,32 @@ class Target {
260266
exit(1)
261267
}
262268

263-
guard let symbolicated = backtrace.symbolicated(with: images,
264-
sharedCacheInfo: sharedCacheInfo,
265-
useSymbolCache: cache) else {
266-
print("unable to symbolicate backtrace from context for thread \(ndx)",
267-
to: &standardError)
268-
exit(1)
269-
}
269+
if symbolicate {
270+
guard let symbolicated = backtrace.symbolicated(with: images,
271+
sharedCacheInfo: sharedCacheInfo,
272+
useSymbolCache: cache) else {
273+
print("unable to symbolicate backtrace from context for thread \(ndx)",
274+
to: &standardError)
275+
exit(1)
276+
}
270277

271-
threads.append(TargetThread(id: info.thread_id,
272-
context: ctx,
273-
name: threadName,
274-
backtrace: symbolicated))
278+
threads.append(TargetThread(id: info.thread_id,
279+
context: ctx,
280+
name: threadName,
281+
backtrace: .symbolicated(symbolicated)))
282+
} else {
283+
threads.append(TargetThread(id: info.thread_id,
284+
context: ctx,
285+
name: threadName,
286+
backtrace: .raw(backtrace)))
287+
}
275288

276289
mach_port_deallocate(mach_task_self_, ports[Int(ndx)])
277290
}
278291
}
279292

280-
public func redoBacktraces(limit: Int?, top: Int, cache: Bool) {
293+
public func redoBacktraces(limit: Int?, top: Int,
294+
cache: Bool, symbolicate: Bool) {
281295
for (ndx, thread) in threads.enumerated() {
282296
guard let context = thread.context else {
283297
continue
@@ -293,15 +307,19 @@ class Target {
293307
continue
294308
}
295309

296-
guard let symbolicated = backtrace.symbolicated(with: images,
297-
sharedCacheInfo: sharedCacheInfo,
298-
useSymbolCache: cache) else {
299-
print("swift-backtrace: unable to symbolicate backtrace from context for thread \(ndx)",
300-
to: &standardError)
301-
continue
302-
}
310+
if symbolicate {
311+
guard let symbolicated = backtrace.symbolicated(with: images,
312+
sharedCacheInfo: sharedCacheInfo,
313+
useSymbolCache: cache) else {
314+
print("swift-backtrace: unable to symbolicate backtrace from context for thread \(ndx)",
315+
to: &standardError)
316+
continue
317+
}
303318

304-
threads[ndx].backtrace = symbolicated
319+
threads[ndx].backtrace = .symbolicated(symbolicated)
320+
} else {
321+
threads[ndx].backtrace = .raw(backtrace)
322+
}
305323
}
306324
}
307325

0 commit comments

Comments
 (0)