What steps will reproduce the problem?
This code sometimes (quite rarely but stable) crashes with EXC_BAD_ACCESS:
GDataXMLNode *child = [element.children objectAtIndex:0];
[element removeChild:child];
This happens because in removeChild: method, 'child' object gets deallocated
(when [self releaseCachedValues] is called) before it's XMLNode is retrieved
and removed from parent.
Initial method is:
- (void)removeChild:(GDataXMLNode *)child {
// this is safe for attributes too
if (xmlNode_ != NULL) {
[self releaseCachedValues]; //<< here child refCount is set to 0 and sometimes it is removed instantly
xmlNodePtr node = [child XMLNode]; //<< as child pointer is invalid, crash occurs here
xmlUnlinkNode(node);
// if the child node was borrowing its xmlNodePtr, then we need to
// explicitly free it, since there is probably no owning object that will
// free it on dealloc
if (![child shouldFreeXMLNode]) {
xmlFreeNode(node);
}
}
}
To avoid crash, the method should be modified as following:
- (void)removeChild:(GDataXMLNode *)child {
// this is safe for attributes too
if (xmlNode_ != NULL) {
xmlNodePtr node = [child XMLNode];
xmlUnlinkNode(node);
// if the child node was borrowing its xmlNodePtr, then we need to
// explicitly free it, since there is probably no owning object that will
// free it on dealloc
if (![child shouldFreeXMLNode]) {
xmlFreeNode(node);
}
[self releaseCachedValues]; //<< we release child collection after we finished accessing 'child'
}
}
Original issue reported on code.google.com by feedback.gm@gmail.com on 6 Jun 2012 at 1:44
Original issue reported on code.google.com by
feedback.gm@gmail.com
on 6 Jun 2012 at 1:44