swiftlang / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. This fork is used to manage Swift’s stable releases of Clang as well as support the Swift project.
https://llvm.org
Other
1.12k stars 332 forks source link

[SR-15375] lldb: --batch -k doesn't always trigger on crash #4301

Open weissi opened 2 years ago

weissi commented 2 years ago
Previous ID SR-15375
Radar rdar://problem/84550421
Original Reporter @weissi
Type Bug
Environment swift-5.5 release on the `swift:5.5-focal` docker image.
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | LLDB for Swift | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: b05f80d34cacf2fcbb48c008f7233815

Issue Description:

intro

I have a program (repro.swift, reproduced at the bottom of this ticket) which crashes sometimes but on Linux only (due to SR-15368).

So I thought, let's see where exactly it crashes using LLDB like so:

lldb --batch -k bt -k 'exit 123' -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run -o run  ./repro

or, do make it less annoying to type

swiftc repro.swift && lldb --batch -k bt -k "exit 123" $(for f in $(seq 50); do echo -o run; done) ./repro

expected

I would expect that the program runs, runs, runs, until it crashes. Then it should print the backtrace and exit LLDB.

actual

$ docker run -it --rm --privileged -v "$PWD:$PWD" -w "$PWD" swift:5.5-focal bash -c 'swiftc repro.swift && lldb --batch -k bt -k "exit 123" $(for f in $(seq 50); do echo -o run; done) ./repro'
(lldb) target create "./repro"
Current executable set to '/tmp/repro' (x86_64).
(lldb) run
Process 47 exited with status = 0 (0x00000000) 

[...]

Process 1433 launched: '/tmp/repro' (x86_64)
(lldb) run
Process 1499 exited with status = 0 (0x00000000) 

Process 1499 launched: '/tmp/repro' (x86_64)
(lldb) run
Process 1565 stopped
* thread #​53, name = 'repro', stop reason = signal SIGSEGV: invalid address (fault address: 0xfffffffffffffff8)
    frame #​0: 0x00007ffff7bcf9dd libswiftCore.so`Swift._ContiguousArrayStorage.__deallocating_deinit + 13
libswiftCore.so`Swift._ContiguousArrayStorage.__deallocating_deinit:
->  0x7ffff7bcf9dd <+13>: movq   -0x8(%rdx), %rax
    0x7ffff7bcf9e1 <+17>: movzbl 0x50(%rax), %edi
    0x7ffff7bcf9e5 <+21>: leal   0x20(%rdi), %eax
    0x7ffff7bcf9e8 <+24>: notl   %edi
Target 0: (repro) stopped.

Process 1565 launched: '/tmp/repro' (x86_64)
(lldb) run
Process 1565 exited with status = 9 (0x00000009) 
Process 1631 exited with status = 0 (0x00000000) 

Process 1631 launched: '/tmp/repro' (x86_64)

Notice how after the crash it just continues and doesn't run the bt.

And please note that this doesn't happen for all programs, something seems to be special about this one.

Repro from macOS (with docker)

docker run -it --rm --privileged -v "$PWD:$PWD" -w "$PWD" swift:5.5-focal bash -c 'swiftc repro.swift && lldb --batch -k bt -k "exit 123" $(for f in $(seq 50); do echo -o run; done) ./repro'

The repro program

import Foundation
import Dispatch

let threads = 60
let sem1 = DispatchSemaphore(value: 0)
let sem2 = DispatchSemaphore(value: 0)
let g = DispatchGroup()

(0..<threads).forEach { index in
    DispatchQueue(label: "\(index)").async(group: g) {
        sem1.signal()
        // All threads should be parked here
        sem2.wait()
        precondition(ProcessInfo.processInfo.hostName.utf8.count > 0)
    }
}

(0..<threads).forEach { index in
    sem1.wait()
}
(0..<threads).forEach { index in
    sem2.signal()
}
g.wait()
weissi commented 2 years ago

@swift-ci create

weissi commented 2 years ago

CC jingham@apple.com (JIRA User)