Files
swift-mirror/test/Backtracing/CrashWithThreadsLinux.swift

110 lines
3.1 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift %s -Onone -g -o %t/CrashWithThreads
// RUN: %target-codesign %t/CrashWithThreads
// RUN: not --crash env SWIFT_BACKTRACE=enable=yes,cache=no,swift-backtrace=%backtracer %target-run %t/CrashWithThreads 2>&1 | %FileCheck -vv %s -dump-input-filter=all
// RUN: not --crash env SWIFT_BACKTRACE=enable=yes,cache=no,swift-backtrace=%backtracer,threads=all %target-run %t/CrashWithThreads 2>&1 | %FileCheck -vv %s -dump-input-filter=all
// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime
// UNSUPPORTED: asan
// REQUIRES: executable_test
// REQUIRES: backtracing
// REQUIRES: OS=linux-gnu
// This test proved unstable on Linux so we disabled it while focus is elsewhere,
// as it's not critical function, but it would be nice to restore it one day.
#if canImport(Glibc)
import Glibc
#elseif canImport(Android)
import Android
#else
#error("Unsupported platform")
#endif
let mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
guard unsafe pthread_mutex_init(mutex, nil) == 0 else {
fatalError("pthread_mutex_init failed")
}
func reallyCrashMe() {
print("I'm going to crash now")
let ptr = UnsafeMutablePointer<Int>(bitPattern: 4)!
ptr.pointee = 42
}
func crashMe() {
reallyCrashMe()
}
func lockMutex() {
guard unsafe pthread_mutex_lock(mutex) == 0 else {
fatalError("pthread_mutex_lock failed")
}
}
func unlockMutex() {
guard unsafe pthread_mutex_unlock(mutex) == 0 else {
fatalError("pthread_mutex_unlock failed")
}
}
func spawnThread(_ shouldCrash: Bool) {
var thread: pthread_t = 0
if shouldCrash {
pthread_create(&thread, nil, { _ in
// take mutex
lockMutex()
crashMe()
// this should not be run
unlockMutex()
while (true) {
sleep(10)
}
}, nil)
} else {
pthread_create(&thread, nil, { _ in
while (true) {
sleep(10)
}
}, nil)
}
}
let crashingThreadIndex = (1..<4).randomElement()
lockMutex()
// hold a mutex
for threadIndex in 1..<4 {
spawnThread(threadIndex == crashingThreadIndex)
}
// release mutex
unlockMutex()
while (true) {
sleep(10)
}
// CHECK-NOT: backtraces will be missing information
// CHECK: *** Program crashed: Bad pointer dereference at 0x{{0+}}4 ***
// CHECK: {{Platform: .* Linux}}
// make sure there are no threads before the crashing thread (rdar://164566321)
// and check that we have some vaguely sane and symbolicated threads, including
// a main thread (AFTER the crashed thread) and at least one other thread
// we expect the first thread not to be another thread, it should be the crashing thread instead
// CHECK-NOT: Thread {{[0-9]+( ".*")?}}:
// CHECK: Thread {{[0-9]+}} {{(".*" )?}}crashed:
// CHECK: {{0x[0-9a-f]+}} reallyCrashMe()
// CHECK: Thread {{[0-9]*( ".*")?}}: