Re: Lxml Crash
Stefan Behnel <stefan_ml <at> behnel.de>
2009-03-04 12:19:33 GMT
Alex Klizhentas wrote:
> sometimes i get exception killing apache process. It happens occasionally
> (acually it happened once on my production site), so I have no more logs
> up to the moment,
> [...]
> I will bring in more logs if crash repeats, but I will appreciate any
> ideas/thoughts/comments so I can quickly eliminate/workaround/prevent the
> issue from happening again.
One thing to note is that you are using lxml 2.2alpha1. There were plenty
of bugs that were fixed in 2.2 since then, including a couple of crash
bugs. I'd try to switch to 2.2beta4 ASAP.
http://codespeak.net/lxml/dev/changes-2.2beta4.html
> I can only suspect that crash happens when I am trying to
> replace the node:
>
> def replace(self,child,new_child):
> root = self.getroottree().getroot()
> index = self.index(child)
> if root._should_notify():
> old_child = deepcopy(child)
> self.insert(index,new_child)
> etree.ElementBase.remove(self,child)
> root._notify(NodeReplaced(old_child,new_child))
> return self[index]
> else:
> self.insert(index,new_child)
> etree.ElementBase.remove(self,child)
> return self[index]
Regarding this code, I assume that "self" is an ElementBase subtype. I
wonder why you didn't write it like this:
def replace(self,child,new_child):
etree.ElementBase.replace(self, child, new_child)
root = self.getroottree().getroot()
if root._should_notify():
root._notify(NodeReplaced(child, new_child))
return new_child
BTW, is your tree protected against concurrent modification in any way? If
your environment (mod_python?) is configured to run requests in parallel,
concurrently replacing a child of the same parent may lead to crashes.
> crash log is below:
>
> *** glibc detected *** /usr/sbin/apache2: free(): invalid pointer:
> 0x08cd6eca ***
> ======= Backtrace: =========
> /lib/tls/i686/cmov/libc.so.6[0xb7e26a85]
> /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7e2a4f0]
> /usr/lib/libxml2.so.2(xmlFreeNodeList+0x126)[0xa984d1e6]
> /usr/lib/libxml2.so.2(xmlFreeNode+0x76)[0xa984d656]
> /usr/lib/python2.5/site-packages/lxml-2.2alpha1-py2.5-linux-i686.egg/lxml/etree.so[0xa9992bf2]
> /usr/lib/python2.5/site-packages/lxml-2.2alpha1-py2.5-linux-i686.egg/lxml/etree.so[0xa99b529f]
All I can see here is that this happens when freeing a node or subtree.
Not much I can extract from that.
Stefan