[lxml-dev] thread-related crash when using xslt
Stefan Behnel
stefan_ml at behnel.de
Fri Feb 27 12:41:43 CET 2009
Hi,
Martijn Faassen wrote:
> Attached is a small tarball that demonstrates code that crashes when the
> code is run in a thread but doesn't crash when it is run stand-alone. I
> isolated the specific XSLT + XML combination that seems to trigger this
> crash. I suspect it has to do with passing an XSLT object to a thread.
Ok, this is plain evil. What you do here is this:
...
<tr class="odd">
<xsl:attribute name="class">top-row</xsl:attribute>
...
Note how the attribute value is changed after being set. In libxslt, this
leads to a result tree update that removes the old attribute and replaces
it by the new one.
In your case, the stylesheet that was parsed outside the thread inherits
the name dict from the main thread, while the input document inherits the
one from the worker thread that executes this function:
def render(id, xml, stylesheet):
doc = etree.parse(StringIO(xml))
result_tree = stylesheet(doc)
So the first "class" attribute name comes from the stylesheet dict and gets
stored in the result document that inherits the thread dict of the input
document. When it is overwritten and deleted, it is looked up in the thread
dict, is not found there, and thus free()-ed, although it continues to
'live' in the stylesheet dict.
This must really be the only place in XSLT where the result document is not
only created incrementally but where its existing content gets overwritten.
For now, I really do not know how to work around this. There can only be
one dict for the result document, but the original attribute can come from
the stylesheet or the input document (or even the current thread dict where
the XSLT is executed), and the dict lookup happens from deep inside libxslt.
I'm very open to ideas.
Stefan
More information about the lxml-dev
mailing list