[lxml-dev] Lxml Crash

Stefan Behnel stefan_ml at behnel.de
Wed Mar 4 13:19:33 CET 2009


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



More information about the lxml-dev mailing list