-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Open
Labels
Description
Previous ID | SR-12079 |
Radar | rdar://problem/58997211 |
Original Reporter | @weissi |
Type | Bug |
Attachment: Download
Additional Detail from JIRA
Votes | 1 |
Component/s | Foundation |
Labels | Bug, Crash |
Assignee | None |
Priority | Medium |
md5: 507eb4e7b2c1f88b3f62677d14f5efd3
Issue Description:
The following program always opens 1000 Pipe
s (sequentially), then sets up a readabilityHandler
for each of the pipes, then closes the other end of the pipe, and waits for the readabilityHandlers to send an empty Data
meaning EOF.
This works for a while until we get a SEGFAULT in dispatch here
(lldb) run
......................Process 24 stopped
* thread #​2, name = 'File', stop reason = signal SIGSEGV: invalid address (fault address: 0xffff800013ff70b7)
frame #​0: 0x00007ffff60b516a libdispatch.so`_dispatch_event_loop_drain + 1242
libdispatch.so`_dispatch_event_loop_drain:
-> 0x7ffff60b516a <+1242>: movl 0x8(%rcx), %edx
0x7ffff60b516d <+1245>: cmpl $0x7fffffff, %edx ; imm = 0x7FFFFFFF
0x7ffff60b5173 <+1251>: je 0x7ffff60b5187 ; <+1271>
0x7ffff60b5175 <+1253>: movl $0x2, %edx
Target 0: (File) stopped.
[...]
* thread #​2, name = 'File', stop reason = signal SIGSEGV: invalid address (fault address: 0xffff800013ff70b7)
* frame #​0: 0x00007ffff60b516a libdispatch.so`_dispatch_event_loop_drain + 1242
frame #​1: 0x00007ffff60a8ea2 libdispatch.so`_dispatch_mgr_invoke + 146
frame #​2: 0x00007ffff60a8dee libdispatch.so`_dispatch_mgr_thread + 126
frame #​3: 0x00007ffff60ac993 libdispatch.so`_dispatch_worker_thread + 515
frame #​4: 0x00007ffff6a826db libpthread.so.0`start_thread + 219
frame #​5: 0x00007ffff5ba388f libc.so.6`clone + 63
Please note that the fault address is 0xffff800013ff70b7
and given that the pointer value ends in 7
and we're looking at a 32 bit load, this looks like a nice memory corruption to because that's an unaligned 32 bit load which is unlikely to be how the code is meant to work.
Credit to rignatus (JIRA User) for finding the initial issue that led to us debugging this together.
Repro:
On Linux
swiftc -O File.swift && ./File
With lldb in Docker (runnable from macOS)
# assuming File is in .
docker run --privileged --rm -v "$PWD:$PWD" -w "$PWD" -it norionomura/swift:nightly bash -c 'swiftc -O File.swift && lldb --batch -o run -k "image list" -k "register read" -k "bt all" -k "exit 134" ./File'
program reproduced here
import Foundation
for i in 1..<1_000_000 {
fputs(".", stdout)
fflush(stdout)
if i % 100 == 0 {
fputs("\n", stdout)
}
let g = DispatchGroup()
let ps = (0..<1000).map { _ in Pipe() }
ps.forEach { p in
var numberOfCalls = 0
g.enter()
p.fileHandleForReading.readabilityHandler = { handle in
if handle.availableData.isEmpty {
numberOfCalls += 1
precondition(numberOfCalls == 1)
g.leave()
}
}
}
ps.forEach { p in
try! p.fileHandleForWriting.close()
}
g.wait()
}