swiftlang / swiftlang/swift-corelibs-libdispatch
[SR-3097] Empty DispatchData returns a nil pointer in withUnsafeBytes
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 2.6k
- Forks
- 496
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 3
Description
| Previous ID | SR-3097 |
| Radar | None |
| Original Reporter | @karwa |
| Type | Bug |
Environment
Swift 3
Additional Detail from JIRA
| Votes | 0 |
| Component/s | libdispatch |
| Labels | Bug, RunTimeCrash |
| Assignee | mww (JIRA) |
| Priority | Medium |
md5: b81d63c73d62a0030cc60459e73a98fc
relates to:
- SR-2976 [Swift 4] Add an UnsafeBufferPointer.empty API
Issue Description:
I have an API which accepts a Foundation Data, and I'm trying to feed it the bytes I read from DispatchIO.read (which come packaged as a DispatchData). The following code (which is the best solution I could find to bridge from DispatchData to Foundation's Data without copying) crashes in Swift 3 when the data is empty:
let dispatchData = DispatchData.empty
dispatchData.withUnsafeBytes { (ptr: UnsafePointer<Int8>) -> Void in
// We make the pointer mutating, but the Data is a `let` so we won't mutate the bytes
let foundationData = Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: ptr), count: dispatchData.count, deallocator: .none)
print("\(foundationData)")
}
The root of the problem seems to be that the Swift dispatch overlay is returning a null-pointer as non-optional, and it gets dereferenced somewhere.
* thread #​1: tid = 0xda386b, 0x000000010067c557 libswiftDispatch.dylib`Dispatch.DispatchData.withUnsafeBytes <A, B> (body : (Swift.UnsafePointer<B>) throws -> A) throws -> A + 215, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
* frame #​0: 0x000000010067c557 libswiftDispatch.dylib`Dispatch.DispatchData.withUnsafeBytes <A, B> (body : (Swift.UnsafePointer<B>) throws -> A) throws -> A + 215
frame #​1: 0x00000001006f80f2 $__lldb_expr38`main + 242 at repl.swift:42
frame #​2: 0x0000000100001420 repl_swift`_mh_execute_header + 5152
frame #​3: 0x00000001000014c8 repl_swift`main + 168 at main.swift:46
frame #​4: 0x00007fffea293255 libdyld.dylib`start + 1
frame #​5: 0x00007fffea293255 libdyld.dylib`start + 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the Dispatch.DispatchData.withUnsafeBytes entry point shown in the stack trace and run the empty DispatchData reproducer under Swift 3. Trace how the empty buffer pointer is passed to the callback. Done means the reproducer no longer crashes and an empty DispatchData can be bridged to Data successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100