[swift-users] UnsafeMutableRawPointer to UnsafeMutablePointer<T>: EXC_BAD_ACCESS on pointee

Braden Scothern bradenscothern at gmail.com
Sat Sep 23 23:16:05 CDT 2017


After doing some testing I looked up the implementation and Unmanaged it is
very misleading in how it is behaves and is implemented.

When you call toOpaque() it returns the result of unsafeBitCast(_value, to:
UnsafeRawPointer.self). _value is an internal field we can't directly
access, in your case it is the c object passed in.

So it seems like it isn't returning a proper UnsafeRawPointer struct.

If you change your let c = C() into var c = C() you can call

withUnsafeMutablePointer(to: &c) { unsafeMutablePointer in
    print(unsafeMutablePointer)
    print(rawPointer)
}

It will print out different values for the 2 pointers even though they
should be the same. If you test with withUnsafePointer(to:_:) it will give
the closure pointer same address as the unsafeMutablePointer here.

If you need an UnsafeMutablePointer<C> you will need to do something like
this (the pointer passed in is only considered valid for the lifetime of
the closure):

let pointer = withUnsafeMutablePointer(to: &c) {
    return UnsafeMutablePointer<C>($0)
}

If you are fine to use the UnsafeRawPointer from toOpaque(), you can
convert it back into c with:

Unmanaged<C>.fromOpaque(rawPointer).takeUnretainedValue()

Hopefully this helped a bit.


On Sat, Sep 23, 2017 at 4:44 PM, Michael Ilseman via swift-users <
swift-users at swift.org> wrote:

>
> > On Sep 23, 2017, at 3:44 AM, nyg nyg via swift-users <
> swift-users at swift.org> wrote:
> >
> > Hello all,
> >
> > I'm trying to get an UnsafeMutablePointer from an
> > UnsafeMutableRawPointer obtained using the Unmanaged structure:
> >
> > class C { var foo = 42, bar = "bar" }
> > let c = C()
> >
> > let rawPointer = Unmanaged.passUnretained(c).toOpaque()
> >
>
> I believe that the object ā€œcā€ is effectively dead from this point onwards.
> Did you try putting a use of c later on to guarantee its lifetime? E.g. add
> a `dump(c)` at the bottom of your script?
>
> > let pointer = rawPointer.bindMemory(to: C.self, capacity: 1)
> > let pointee = pointer.pointee
> > print(pointee.foo) // EXC_BAD_ACCESS
> >
> > Here's some LLDB output, which looks strange to me as everything seems
> > alright in pointer until I ask for its pointee:
> >
> > (lldb) frame variable -L c
> > scalar: (memtest2.C) c = 0x0000000101d00030 {
> > 0x0000000101d00040: foo = 42
> > 0x0000000101d00048: bar = "bar"
> > }
> > (lldb) frame variable -L rawPointer
> > 0x00000001005e2e08: (UnsafeMutableRawPointer) rawPointer = {
> > scalar: _rawValue = 0x0000000101d00030 {
> > 0x0000000101d00040: foo = 42
> > 0x0000000101d00048: bar = "bar"
> > }
> > }
> > (lldb) frame variable -L pointer
> > 0x00000001005e2e10: (UnsafeMutablePointer<memtest2.C>)
> >                                            pointer = 0x0000000101d00030
> > (lldb) frame variable -L pointer._rawValue
> > scalar: (memtest2.C) pointer._rawValue = 0x0000000101d00030 {
> > 0x0000000101d00040: foo = 42
> > 0x0000000101d00048: bar = "bar"
> > }
> > (lldb) frame variable -L pointee
> > 0x00000001005e2e18: (memtest2.C) pointee = 0x00000001005b65d8 {
> > 0x00000001005b65e8: foo = 140736790071664
> > 0x00000001005b65f0: bar = ""
> > }
> >
> > I've also tried assumingMemoryBound(to:) or simply doing:
> >
> > let pointer = UnsafePointer<C>(bitPattern: Int(bitPattern: rawPointer))!
> > print(pointer.pointee.foo) // EXC_BAD_ACCESS
> >
> > But I always get this EXC_BAD_ACCESS error. What is going on here?
> >
> >
> > Thanks for your help,
> > Nick
> > _______________________________________________
> > swift-users mailing list
> > swift-users at swift.org
> > https://lists.swift.org/mailman/listinfo/swift-users
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170923/34d8bcd4/attachment.html>


More information about the swift-users mailing list