Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fuzi 0.1.1, iOS9, Swift 2] XMLElement.firstChild(...) crash: "libswiftCore.dylib`_swift_abortRetainUnowned:", "attempted to retain deallocated object". #1

Closed
razvandub opened this issue Sep 29, 2015 · 6 comments

Comments

@razvandub
Copy link

Input:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header />
    <SOAP-ENV:Body>
        <sub:rr xmlns:sub="http://www.rr.com/schema">
            <sub:error>
                <sub:code>1234</sub:code>
            </sub:error>
        </sub:rr>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>"

Code:

...
guard let rootXML = try? XMLDocument(data: responseEnvelopeData).root else {
   ...
}

...

if let _ = rootXML?.firstChild(tag: "Body")?.firstChild(tag: "rr")?.firstChild(tag: "error")?.stringValue {
... 
}

...

Crash:

(lldb) bt

  • thread Any chance u would provide a guide video or article? #15: tid = 0x6b9ffb, 0x0000000108b1899f libswiftCore.dylib`_swift_abortRetainUnowned + 15, queue = 'NSOperationQueue 0x7fcf91d2fb50 :: NSOperation 0x7fcf91e4f7b0 (QOS: LEGACY)', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
    • frame #0: 0x0000000108b1899f libswiftCore.dylib_swift_abortRetainUnowned + 15 frame #1: 0x0000000108b18986 libswiftCore.dylibswift_retainUnowned + 38
      frame Accessing parents children #2: 0x0000000105a2398b Fuzi`Fuzi.XMLElement.firstChild (tag="Body", ns=nil, self=0x00007fcf91e50290)(tag : Swift.String, inNamespace : Swift.Optional<Swift.String>) -> Swift.Optional<Fuzi.XMLElement> + 411 at Element.swift:81
      ...
@cezheng
Copy link
Owner

cezheng commented Sep 29, 2015

@razvandub Hello thanks for the feedback. The reason why this happens is that an XMLElement holds a weak reference to the document and in your code there is no strong reference to the document and it is released after you get the root element.

Changing your code to this will resolve your issue

...
guard let doc = try? XMLDocument(data: responseEnvelopeData) else {
   ...
}

...

if let _ = doc.root?.firstChild(tag: "Body")?.firstChild(tag: "rr")?.firstChild(tag: "error")?.stringValue {
... 
}

...

@razvandub
Copy link
Author

Thanks @cezheng, I'll do that for now. Could you please update the readme to make this explicit since Fuzi's mem management is not intuitive and also because this was not the case with 0.1.0? Thanks.

@cezheng
Copy link
Owner

cezheng commented Sep 29, 2015

@razvandub Sorry about that. I was changing this in 0.1.1 to resolve a reference loop between root & document making the document instances never released in 0.1.0, but didn't realized that might be dangerous if users are not properly guided. I appreciate your feedback.

I will put some thoughts on how to make your code not crash first. If I can't come up with a way of doing that I will update the README

@razvandub
Copy link
Author

No problem @cezheng, thanks.

@stepanhruda
Copy link

@cezheng Why do you use unowned rather than weak?

@cezheng
Copy link
Owner

cezheng commented Oct 29, 2015

@stepanhruda There're 2 reasons I don't use weak

  • because weak can only be used on a mutable optional, and an XMLElement cannot function properly if the document is nil.
  • when the document is deallocated, the underlying libxml2 document will be freed as well, i.e. the underlying libxml2 node of the document is also freed, still making code like this to crash.

So currently, the proper way to use this library is to keep a strong reference on the document rather than the element. If you have any thoughts on improving this, I will appreciate it if you could share your thoughts or even a PR

@cezheng cezheng closed this as completed Jun 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants