Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion stdlib/public/Backtracing/BacktraceFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,16 @@ public struct BacktraceFormatter {
// sourceLocation.column is an index in UTF-8 code units in
// `untabified`. We should point at the grapheme cluster that
// contains that UTF-8 index.
let adjustedColumn = max(sourceLocation.column, 1)
let adjustedColumn: Int
if sourceLocation.column > 0 {
adjustedColumn = sourceLocation.column
} else {
if let ndx = code.firstIndex(where: { $0 != " " }) {
adjustedColumn = code.distance(from: code.startIndex, to: ndx) + 1
} else {
adjustedColumn = 1
}
}
let utf8Ndx
= untabified.utf8.index(untabified.utf8.startIndex,
offsetBy: adjustedColumn,
Expand Down
6 changes: 1 addition & 5 deletions stdlib/public/Backtracing/FramePointerUnwinder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@

import Swift

// @available(SwiftStdlib 5.1, *)
@_silgen_name("swift_task_getCurrent")
func _getCurrentAsyncTask() -> UnsafeRawPointer?

@_spi(Unwinders)
public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, IteratorProtocol {
public typealias Context = C
Expand Down Expand Up @@ -47,7 +43,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
#if (os(macOS) || os(iOS) || os(watchOS)) && (arch(arm64) || arch(arm64_32) || arch(x86_64))
// On Darwin, we borrow a bit of the frame pointer to indicate async
// stack frames
return (storedFp & (1 << 60)) != 0 && _getCurrentAsyncTask() != nil
return (storedFp & (1 << 60)) != 0
#else
return false
#endif
Expand Down
12 changes: 9 additions & 3 deletions stdlib/public/Backtracing/SymbolicatedBacktrace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,17 @@ public struct SymbolicatedBacktrace: CustomStringConvertible {
if rawName == "start" && imageName == "dyld" {
return true
}
if let location = sourceLocation,
location.line == 0 && location.column == 0 {
if rawName.hasSuffix("5$mainyyFZ")
|| rawName.hasSuffix("5$mainyyYaFZTQ0_")
|| rawName == "_async_MainTQ0_" {
return true
}
if rawName == "__ZL23completeTaskWithClosurePN5swift12AsyncContextEPNS_10SwiftErrorE" && imageName == "libswift_Concurrency.dylib" {
return true
}
if rawName.hasSuffix("5$mainyyFZ") {
if let location = sourceLocation,
location.line == 0 && location.column == 0
&& !_swift_isThunkFunction(rawName) {
return true
}
#endif
Expand Down
99 changes: 99 additions & 0 deletions test/Backtracing/CrashAsync.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift %s -parse-as-library -Onone -g -o %t/CrashAsync
// RUN: %target-codesign %t/CrashAsync

// Demangling is disabled for now because older macOS can't demangle async
// function names. We test demangling elsewhere, so this is no big deal.

// RUN: (env SWIFT_BACKTRACE=enable=yes,demangle=no,cache=no %target-run %t/CrashAsync || true) | %FileCheck %s
// RUN: (env SWIFT_BACKTRACE=preset=friendly,enable=yes,demangle=no,cache=no %target-run %t/CrashAsync || true) | %FileCheck %s --check-prefix FRIENDLY

// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime
// REQUIRES: executable_test
// REQUIRES: backtracing
// REQUIRES: OS=macosx

@available(SwiftStdlib 5.1, *)
func crash() {
let ptr = UnsafeMutablePointer<Int>(bitPattern: 4)!
ptr.pointee = 42
}

@available(SwiftStdlib 5.1, *)
func level(_ n: Int) async {
if n < 5 {
await level(n + 1)
} else {
crash()
}
}

@available(SwiftStdlib 5.1, *)
@main
struct CrashAsync {
static func main() async {
await level(1)
}
}

// CHECK: *** Program crashed: Bad pointer dereference at 0x{{0+}}4 ***

// CHECK: Thread {{[0-9]+}} crashed:

// CHECK: 0 0x{{[0-9a-f]+}} _$s10CrashAsync5crashyyF + {{[0-9]+}} in CrashAsync at {{.*}}/CrashAsync.swift:20:15
// CHECK-NEXT: 1 [ra] 0x{{[0-9a-f]+}} _$s10CrashAsync5levelyySiYaFTY0_ + {{[0-9]+}} in CrashAsync at {{.*}}/CrashAsync.swift:28:5
// CHECK-NEXT: 2 [async] 0x{{[0-9a-f]+}} _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}/CrashAsync.swift:26
// CHECK-NEXT: 3 [async] 0x{{[0-9a-f]+}} _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}/CrashAsync.swift:26
// CHECK-NEXT: 4 [async] 0x{{[0-9a-f]+}} _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}/CrashAsync.swift:26
// CHECK-NEXT: 5 [async] 0x{{[0-9a-f]+}} _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}/CrashAsync.swift:26
// CHECK-NEXT: 6 [async] 0x{{[0-9a-f]+}} _$s10CrashAsyncAAV4mainyyYaFZTQ0_ in CrashAsync at {{.*}}/CrashAsync.swift:36
// CHECK-NEXT: 7 [async] [system] 0x{{[0-9a-f]+}} _$s10CrashAsyncAAV5$mainyyYaFZTQ0_ in CrashAsync at {{.*}}/<compiler-generated>
// CHECK-NEXT: 8 [async] [system] 0x{{[0-9a-f]+}} _async_MainTQ0_ in CrashAsync at {{.*}}/<compiler-generated>
// CHECK-NEXT: 9 [async] [thunk] 0x{{[0-9a-f]+}} _$sIetH_yts5Error_pIegHrzo_TRTQ0_ in CrashAsync at {{.*}}/<compiler-generated>
// CHECK-NEXT: 10 [async] [thunk] 0x{{[0-9a-f]+}} _$sIetH_yts5Error_pIegHrzo_TRTATQ0_ in CrashAsync at {{.*}}/<compiler-generated>
// CHECK-NEXT: 11 [async] [system] 0x{{[0-9a-f]+}} __ZL23completeTaskWithClosurePN5swift12AsyncContextEPNS_10SwiftErrorE in libswift_Concurrency.dylib at {{.*}}/Task.cpp:463

// FRIENDLY: *** Program crashed: Bad pointer dereference at 0x{{0+}}4 ***

// FRIENDLY: Thread {{[0-9]+}} crashed:

// FRIENDLY: 0 _$s10CrashAsync5crashyyF + {{[0-9]+}} in CrashAsync at {{.*}}CrashAsync.swift:20:15

// FRIENDLY: 18| func crash() {
// FRIENDLY-NEXT: 19| let ptr = UnsafeMutablePointer<Int>(bitPattern: 4)!
// FRIENDLY-NEXT: * 20| ptr.pointee = 42
// FRIENDLY-NEXT: | ^
// FRIENDLY-NEXT: 21| }
// FRIENDLY-NEXT: 22|

// FRIENDLY: 1 _$s10CrashAsync5levelyySiYaFTY0_ + {{[0-9]+}} in CrashAsync at {{.*}}CrashAsync.swift:28:5

// FRIENDLY: 26| await level(n + 1)
// FRIENDLY-NEXT: 27| } else {
// FRIENDLY-NEXT: * 28| crash()
// FRIENDLY-NEXT: | ^
// FRIENDLY-NEXT: 29| }
// FRIENDLY-NEXT: 30| }

// FRIENDLY:2 _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}CrashAsync.swift:26

// FRIENDLY: 24| func level(_ n: Int) async {
// FRIENDLY-NEXT: 25| if n < 5 {
// FRIENDLY-NEXT: * 26| await level(n + 1)
// FRIENDLY-NEXT: | ^
// FRIENDLY-NEXT: 27| } else {
// FRIENDLY-NEXT: 28| crash()

// FRIENDLY: 3 _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}CrashAsync.swift:26
// FRIENDLY: 4 _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}CrashAsync.swift:26
// FRIENDLY: 5 _$s10CrashAsync5levelyySiYaFTQ1_ in CrashAsync at {{.*}}CrashAsync.swift:26
// FRIENDLY: 6 _$s10CrashAsyncAAV4mainyyYaFZTQ0_ in CrashAsync at {{.*}}CrashAsync.swift:36

// FRIENDLY: 34| struct CrashAsync {
// FRIENDLY-NEXT: 35| static func main() async {
// FRIENDLY-NEXT: * 36| await level(1)
// FRIENDLY-NEXT: | ^
// FRIENDLY-NEXT: 37| }
// FRIENDLY-NEXT: 38| }

10 changes: 5 additions & 5 deletions test/Backtracing/CrashWithThunk.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ struct CrashWithThunk {

// CHECK: Thread 0 crashed:

// CHECK: 0 0x{{[0-9a-f]+}} crash() + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift:20:15
// CHECK-NEXT: 1 [ra] [thunk] [system] 0x{{[0-9a-f]+}} thunk for @escaping @callee_guaranteed () -> () + {{[0-9]+}} in CrashWithThunk at {{.*}}/Backtracing/<compiler-generated>
// CHECK-NEXT: 2 [ra] 0x{{[0-9a-f]+}} static CrashWithThunk.main() + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift:28:9
// CHECK-NEXT: 3 [ra] [system] 0x{{[0-9a-f]+}} static CrashWithThunk.$main() + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift:23:1
// CHECK-NEXT: 4 [ra] [system] 0x{{[0-9a-f]+}} main + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift
// CHECK: 0 0x{{[0-9a-f]+}} crash() + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift:20:15
// CHECK-NEXT: 1 [ra] [thunk] 0x{{[0-9a-f]+}} thunk for @escaping @callee_guaranteed () -> () + {{[0-9]+}} in CrashWithThunk at {{.*}}/Backtracing/<compiler-generated>
// CHECK-NEXT: 2 [ra] 0x{{[0-9a-f]+}} static CrashWithThunk.main() + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift:28:9
// CHECK-NEXT: 3 [ra] [system] 0x{{[0-9a-f]+}} static CrashWithThunk.$main() + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift:23:1
// CHECK-NEXT: 4 [ra] [system] 0x{{[0-9a-f]+}} main + {{[0-9]+}} in CrashWithThunk at {{.*}}/CrashWithThunk.swift

// CHECK: Registers:

Expand Down