Description
Previous ID | SR-3628 |
Radar | None |
Original Reporter | @weissi |
Type | Bug |
Status | Resolved |
Resolution | Done |
Attachment: Download
Additional Detail from JIRA
Votes | 0 |
Component/s | libdispatch |
Labels | Bug, RunTimeCrash |
Assignee | @weissi |
Priority | Medium |
md5: 2e06178945d3f56e3269faeaa6f8a4b4
Issue Description:
Description
The following program is supposed to read a gigabyte from /dev/zero
and one second after reading it, checking that all bytes are 0
that come back. Pretty useless program but bear with me 🙂.
import Dispatch
#if os(Linux)
import Glibc
#else
import Darwin
#endif
import Foundation
let q = DispatchQueue(label: "q")
let fd = open("/dev/zero", O_RDONLY)
let chan = DispatchIO(type: .stream, fileDescriptor: fd, queue: q) { err in
print("ERR = \(err)")
}
chan.setLimit(lowWater: 1)
chan.read(offset: 0, length: 1024*1024*1024, queue: q) { done, mData, err in
if err != 0 {
print("READ ERR \(err)")
}
if let data = mData {
q.asyncAfter(deadline: .now() + 1.0) {
data.enumerateBytes { (p: UnsafeBufferPointer<UInt8>, _, _) in
var q = p.baseAddress!
for f in 0..<p.count {
precondition(q.pointee == 0, "POST: was \(q.pointee) instead of 0 at \(f) out of \(p.count)")
q = q.successor()
}
}
}
}
}
dispatchMain()
Expected
Nothing happens, program just runs, prints nothing and never exits
Actual
On macOS the expected behaviour is exhibited. On Linux however (tested with 3.0.1 release, 3.0.2 release and Swift version 3.1-dev (LLVM c3e057b06a, Clang 0540ceb7ad, Swift d3857f6071)
), I get two different crashes
h3 Crash 1
it's faulting at address 0x68
which is clearly a NULL pointer
(lldb) run
There is a running process, kill it and restart?: [Y/n]
Process 2961 exited with status = 9 (0x00000009)
Process 2986 launched: './repro' (x86_64)
Process 2986 stopped
* thread #​5: tid = 2993, 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26, name = 'repro', stop reason = signal SIGSEGV: invalid address (fault address: 0x68)
frame #​0: 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26
libdispatch.so`_dispatch_data_apply:
-> 0x7ffff7f1055a <+26>: movq 0x48(%r12), %rdi
0x7ffff7f1055f <+31>: cmpq $0x1, %rdi
0x7ffff7f10563 <+35>: jne 0x7ffff7f10575 ; <+53>
0x7ffff7f10565 <+37>: movq 0x50(%r12), %rsi
(lldb) bt
* thread #​5: tid = 2993, 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26, name = 'repro', stop reason = signal SIGSEGV: invalid address (fault address: 0x68)
* frame #​0: 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26
frame #​1: 0x00007ffff7f105d9 libdispatch.so`_dispatch_data_apply + 153
frame #​2: 0x00007ffff7f1063c libdispatch.so`dispatch_data_apply + 28
frame #​3: 0x00007ffff7f29506 libdispatch.so`_TFV8Dispatch12DispatchData14enumerateBytesfT5blockFTGSRVs5UInt8_SiRSb_T__T_ + 182
frame #​4: 0x0000000000402877 repro`_TFF5reproU0_FTSbGSqV8Dispatch12DispatchData_Vs5Int32_T_U_FT_T_ + 39 at repro.swift:27
frame #​5: 0x0000000000402dc7 repro`_TTRXFo___XFdCb___ + 39 at repro.swift:0
frame #​6: 0x00007ffff7f1b8a2 libdispatch.so`_dispatch_continuation_pop + 258
frame #​7: 0x00007ffff7f220e3 libdispatch.so`_dispatch_source_invoke + 1139
frame #​8: 0x00007ffff7f1d25a libdispatch.so`_dispatch_queue_serial_drain + 570
frame #​9: 0x00007ffff7f1d941 libdispatch.so`_dispatch_queue_invoke + 849
frame #​10: 0x00007ffff7f1f9b9 libdispatch.so`_dispatch_root_queue_drain + 393
frame #​11: 0x00007ffff7f43f68 libdispatch.so`overcommit_worker_main(unused=<unavailable>) + 152 at manager.c:315
frame #​12: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​13: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
(lldb) register read
General Purpose Registers:
rax = 0x0000000000000010
rbx = 0x00007fffd4000980
rcx = 0x0000000000000010
rdx = 0x0000000000000054
rdi = 0x0000000000000020
rsi = 0x0000000000000000
rbp = 0x0000000000000001
rsp = 0x00007fffec842a20
r8 = 0x00007fffdc000d80
r9 = 0x00007ffff7f29540 libdispatch.so`_TTRXFo_dVs13OpaquePointerdSidSVdSi_dSb_XFdCb_dS_dSidSVdSi_dSb_
r10 = 0x00007fffdc000d70
r11 = 0x00007ffff7f74380 _dispatch_mgr_q
r12 = 0x0000000000000020
r13 = 0x0000000000000000
r14 = 0x00007ffff7f29540 libdispatch.so`_TTRXFo_dVs13OpaquePointerdSidSVdSi_dSb_XFdCb_dS_dSidSVdSi_dSb_
r15 = 0x00007fffdc000d80
rip = 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26
rflags = 0x0000000000010246
cs = 0x0000000000000033
fs = 0x0000000000000000
gs = 0x0000000000000000
ss = 0x000000000000002b
ds = 0x0000000000000000
es = 0x0000000000000000
backtraces for all threads
(lldb) bt all
thread #​1: tid = 3268, 0x00007ffff5c85826 libc.so.6`__GI___sigsuspend(set=0x00007ffff7f48c58) + 86 at sigsuspend.c:30, name = 'repro'
frame #​0: 0x00007ffff5c85826 libc.so.6`__GI___sigsuspend(set=0x00007ffff7f48c58) + 86 at sigsuspend.c:30
frame #​1: 0x00007ffff7f20388 libdispatch.so`_dispatch_sigsuspend + 24
frame #​2: 0x00007ffff7f1e756 libdispatch.so`_dispatch_sig_thread + 6
frame #​3: 0x00007ffff77d7489 libpthread.so.0`__nptl_deallocate_tsd.part.4 + 137
frame #​4: 0x00007ffff5c70854 libc.so.6`__libc_start_main(main=(repro`main), argc=1, argv=0x00007fffffffe498, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe488) + 276 at libc-start.c:297
frame #​5: 0x00000000004020b9 repro`_start + 41
thread #​2: tid = 3271, 0x00007ffff77e0a65 libpthread.so.0`do_futex_wait + 69, name = 'repro'
frame #​0: 0x00007ffff77e0a65 libpthread.so.0`do_futex_wait + 69
frame #​1: 0x00007ffff77e0b2f libpthread.so.0`__new_sem_wait_slow + 95
frame #​2: 0x00007ffff77e0be2 libpthread.so.0`sem_timedwait + 66
frame #​3: 0x00007ffff7f4468c libdispatch.so`manager_main(unused=<unavailable>) + 1148 at manager.c:620
frame #​4: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​5: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​3: tid = 3272, 0x00007ffff77de759 libpthread.so.0`__pthread_cond_timedwait + 297, name = 'repro'
frame #​0: 0x00007ffff77de759 libpthread.so.0`__pthread_cond_timedwait + 297
frame #​1: 0x00007ffff7f43fb4 libdispatch.so`overcommit_worker_main(unused=<unavailable>) + 228 at manager.c:326
frame #​2: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​3: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​4: tid = 3273, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
* thread #​5: tid = 3274, 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26, name = 'repro', stop reason = signal SIGSEGV: invalid address (fault address: 0x68)
* frame #​0: 0x00007ffff7f1055a libdispatch.so`_dispatch_data_apply + 26
frame #​1: 0x00007ffff7f105d9 libdispatch.so`_dispatch_data_apply + 153
frame #​2: 0x00007ffff7f1063c libdispatch.so`dispatch_data_apply + 28
frame #​3: 0x00007ffff7f29506 libdispatch.so`_TFV8Dispatch12DispatchData14enumerateBytesfT5blockFTGSRVs5UInt8_SiRSb_T__T_ + 182
frame #​4: 0x0000000000402877 repro`_TFF5reproU0_FTSbGSqV8Dispatch12DispatchData_Vs5Int32_T_U_FT_T_ + 39 at repro.swift:27
frame #​5: 0x0000000000402dc7 repro`_TTRXFo___XFdCb___ + 39 at repro.swift:0
frame #​6: 0x00007ffff7f1b8a2 libdispatch.so`_dispatch_continuation_pop + 258
frame #​7: 0x00007ffff7f220e3 libdispatch.so`_dispatch_source_invoke + 1139
frame #​8: 0x00007ffff7f1d25a libdispatch.so`_dispatch_queue_serial_drain + 570
frame #​9: 0x00007ffff7f1d941 libdispatch.so`_dispatch_queue_invoke + 849
frame #​10: 0x00007ffff7f1f9b9 libdispatch.so`_dispatch_root_queue_drain + 393
frame #​11: 0x00007ffff7f43f68 libdispatch.so`overcommit_worker_main(unused=<unavailable>) + 152 at manager.c:315
frame #​12: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​13: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​6: tid = 3275, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​7: tid = 3276, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​8: tid = 3277, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​9: tid = 3278, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​10: tid = 3279, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​11: tid = 3280, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​12: tid = 3281, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​13: tid = 3282, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​14: tid = 3283, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​15: tid = 3284, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​16: tid = 3285, 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192, name = 'repro'
frame #​0: 0x00007ffff77de3b0 libpthread.so.0`__pthread_cond_wait + 192
frame #​1: 0x00007ffff7f44feb libdispatch.so`worker_main [inlined] wqlist_scan_wait + 17 at manager.c:451
frame #​2: 0x00007ffff7f44fda libdispatch.so`worker_main(unused=<unavailable>) + 314 at manager.c:493
frame #​3: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​4: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
thread #​17: tid = 3286, 0x00007ffff5d56dca libc.so.6`__GI_epoll_ctl + 10 at syscall-template.S:84, name = 'repro'
frame #​0: 0x00007ffff5d56dca libc.so.6`__GI_epoll_ctl + 10 at syscall-template.S:84
frame #​1: 0x00007ffff7f42f18 libdispatch.so`evfilt_timer_knote_create(filt=<unavailable>, kn=0x00007fffd00008c0) + 504 at timer.c:181
frame #​2: 0x00007ffff7f3ebe0 libdispatch.so`kevent [inlined] kevent_copyin_one(kq=<unavailable>, src=0x00007ffff7ec2ba0) + 676 at kevent.c:149
frame #​3: 0x00007ffff7f3e93c libdispatch.so`kevent [inlined] kevent_copyin(kq=<unavailable>, src=<unavailable>, nchanges=<unavailable>, eventlist=<unavailable>, nevents=<unavailable>) + 122 at kevent.c:204
frame #​4: 0x00007ffff7f3e8c2 libdispatch.so`kevent(kqfd=<unavailable>, changelist=0x00007ffff7ec2ba0, nchanges=<unavailable>, eventlist=<unavailable>, nevents=<unavailable>, timeout=<unavailable>) + 258 at kevent.c:265
frame #​5: 0x00007ffff7f24956 libdispatch.so`_dispatch_mgr_wait_for_event + 70
frame #​6: 0x00007ffff7f23427 libdispatch.so`_dispatch_mgr_invoke + 247
frame #​7: 0x00007ffff7f231fb libdispatch.so`_dispatch_mgr_thread + 11
frame #​8: 0x00007ffff7f1f9b9 libdispatch.so`_dispatch_root_queue_drain + 393
frame #​9: 0x00007ffff7f1f788 libdispatch.so`_dispatch_worker_thread + 408
frame #​10: 0x00007ffff77d870a libpthread.so.0`start_thread + 202
frame #​11: 0x00007ffff5d5682d libc.so.6`__clone + 109 at clone.S:109
Crash 2
$ ./repro
precondition failed: POST: was 64 instead of 0 at 0 out of 2: file repro.swift, line 24
Current stack trace:
0 libswiftCore.so 0x00007f07bc0e2420 swift_reportError + 120
1 libswiftCore.so 0x00007f07bc0fcc40 _swift_stdlib_reportFatalErrorInFile + 100
2 libswiftCore.so 0x00007f07bbefa30c <unavailable> + 1168140
3 libswiftCore.so 0x00007f07bc08ff0d <unavailable> + 2830093
4 libswiftCore.so 0x00007f07bbef9ae6 <unavailable> + 1166054
5 libswiftCore.so 0x00007f07bc095e20 <unavailable> + 2854432
6 libswiftCore.so 0x00007f07bbef9f1f <unavailable> + 1167135
7 libswiftCore.so 0x00007f07bc056a59 <unavailable> + 2595417
8 libswiftCore.so 0x00007f07bbef9ae6 <unavailable> + 1166054
9 libswiftCore.so 0x00007f07bc013af0 specialized _assertionFailure(StaticString, String, file : StaticString, line : UInt, flags : UInt32) -> Never + 144
10 repro 0x0000000000402d67 <unavailable> + 11623
11 libdispatch.so 0x00007f07bc328940 <unavailable> + 432448
12 libdispatch.so 0x00007f07bc31c57e <unavailable> + 382334
13 libdispatch.so 0x00007f07bc3035ad <unavailable> + 279981
14 libdispatch.so 0x00007f07bc303620 dispatch_data_apply + 28
15 libdispatch.so 0x00007f07bc31c450 DispatchData.enumerateBytes(block : (UnsafeBufferPointer<UInt8>, Int, inout Bool) -> ()) -> () + 182
16 repro 0x0000000000402877 <unavailable> + 10359
17 repro 0x0000000000402dc7 <unavailable> + 11719
18 libdispatch.so 0x00007f07bc30e8a2 <unavailable> + 325794
19 libdispatch.so 0x00007f07bc3150e3 <unavailable> + 352483
20 libdispatch.so 0x00007f07bc31025a <unavailable> + 332378
21 libdispatch.so 0x00007f07bc310941 <unavailable> + 334145
22 libdispatch.so 0x00007f07bc3129b9 <unavailable> + 342457
23 libdispatch.so 0x00007f07bc336f68 <unavailable> + 491368
24 libpthread.so.0 0x00007f07bbbc770a <unavailable> + 30474
25 libc.so.6 0x00007f07ba1457c0 clone + 109
Illegal instruction (core dumped)
this one is also interesting as one of the bytes wasn't 0
but 64
. This leads me to think that the DispatchData
is probably already released and still more or less intact in memory. Therefore the pointer to the actual bytes is also still valid(ish) but is dangling and points to a random place in memory where there happens to be a byte with value 64
.