[lxml-dev] Segfault on XSLT/XPath undefined variable error.
John Krukoff
jkrukoff at ltgc.com
Mon Aug 11 20:29:51 CEST 2008
On Fri, 2008-08-08 at 08:25 +0200, Stefan Behnel wrote:
> Hi,
>
> John Krukoff wrote:
> > On Fri, 2008-08-01 at 08:47 +0200, Stefan Behnel wrote:
> >> Hi,
> >>
> >> John Krukoff wrote:
> >>> Okay, can only get it to crash when first signing a document using
> >>> libxmlsec, so I suppose I'll simply assume that the two libraries use
> >>> the error log in incompatible ways.
> >> could you check if this patch makes it work better for you? It basically
> >> restricts XSLT error logging to the lifetime of an XSL transformation.
> >>
> >> Stefan
> >
> > I still need to compile lxml with -ggdb, where do I stick that in the
> > setup.py/makefile?
>
> Pass the "CFLAGS" env variable when calling setup.py, as in
>
> CFLAGS="-O -ggdb" make clean inplace
>
>
> > still crashed with the patch for me:
> >
> > Core was generated by `/usr/bin/python -tt ./Adapter.py'.
> > Program terminated with signal 11, Segmentation fault.
> > #0 0xb774b740 in __pyx_f_4lxml_5etree__forwardError ()
> >
> > from /usr/lib/python2.5/site-packages/lxml-2.1.1-py2.5-linux-i686.egg/lxml/etree.so
> > (gdb) bt
> > #0 0xb774b740 in __pyx_f_4lxml_5etree__forwardError ()
> >
> > from /usr/lib/python2.5/site-packages/lxml-2.1.1-py2.5-linux-i686.egg/lxml/etree.so
> > #1 0xb774bb12 in __pyx_f_4lxml_5etree__receiveXSLTError ()
> >
> > from /usr/lib/python2.5/site-packages/lxml-2.1.1-py2.5-linux-i686.egg/lxml/etree.so
> > #2 0xb76baef9 in xsltPrintErrorContext () from /usr/lib/libxslt.so.1
> > #3 0xb76bb091 in xsltTransformError () from /usr/lib/libxslt.so.1
> > #4 0xb76dd434 in xsltValueOf () from /usr/lib/libxslt.so.1
> > #5 0xb76da5ba in ?? () from /usr/lib/libxslt.so.1
> > #6 0x0878e718 in ?? ()
> > #7 0x08432c60 in ?? ()
> > #8 0x0878ec78 in ?? ()
> > #9 0x0878f6f8 in ?? ()
> > #10 0x00000000 in ?? ()
> >
> > Fortunately, I've been able to simplify my crash conditions somewhat, so
> > the valgrind log is significantly shorter.
>
> You can generally strip the "... within /lib/ld-2.6..." entries from it.
>
>
> > Looks like I'll need to find some time to work on that test case after
> > all.
>
> Please do, and also re-run your valgrind test with -ggdb. There seem to be
> some interesting problems in there (the "moveNodeToDocument()" sections), even
> if only crashes later. Seeing the line numbers here would really be helpful.
>
> Stefan
Okay, I can get a segfault with this minimal test case, where
variable.xslt is the previously sent XSLT sheet which references an
undefined parameter in an xpath expression:
Python 2.5.2 (r252:60911, Jul 31 2008, 15:38:58)
[GCC 4.1.2 (Gentoo 4.1.2 p1.1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
>>> import xmlsig
>>> etree.XSLT( etree.parse( 'variable.xslt' ) )( etree.XML( '<a/>' ) )
xmlXPathCompiledEval: evaluation failed
Segmentation fault
However, changing the import order causes the crash to go away, I assume
due to order of initialization in the logging code:
~/Projects/Gizmo/www/Samples 17$ python
Python 2.5.2 (r252:60911, Jul 31 2008, 15:38:58)
[GCC 4.1.2 (Gentoo 4.1.2 p1.1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xmlsig
>>> from lxml import etree
>>> etree.XSLT( etree.parse( 'variable.xslt' ) )( etree.XML( '<a/>' ) )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "xslt.pxi", line 529, in lxml.etree.XSLT.__call__
(src/lxml/lxml.etree.c:91033)
lxml.etree.XSLTApplyError: XPath evaluation returned no result.
Here is the backtrace from the crash with debugging info:
Core was generated by `python'.
Program terminated with signal 11, Segmentation fault.
#0 0xb78ce53b in __pyx_f_4lxml_5etree__forwardError
(__pyx_v_c_log_handler=<value optimized out>, __pyx_v_error=0xbfba01c8)
at src/lxml/lxml.etree.c:40855
40855 ((struct __pyx_vtabstruct_4lxml_5etree__BaseErrorLog
*)__pyx_v_log_handler->__pyx_vtab)->_receive(__pyx_v_log_handler,
__pyx_v_error);
(gdb) bt
#0 0xb78ce53b in __pyx_f_4lxml_5etree__forwardError
(__pyx_v_c_log_handler=<value optimized out>, __pyx_v_error=0xbfba01c8)
at src/lxml/lxml.etree.c:40855
#1 0xb78ce79c in __pyx_f_4lxml_5etree__receiveXSLTError
(__pyx_v_c_log_handler=0xb75fcf04,
__pyx_v_msg=0xb7880450 "%s: file %s line %d element %s\n") at
src/lxml/lxml.etree.c:41371
#2 0xb7859ef9 in xsltPrintErrorContext () from /usr/lib/libxslt.so.1
#3 0xb785a091 in xsltTransformError () from /usr/lib/libxslt.so.1
#4 0xb787c434 in xsltValueOf () from /usr/lib/libxslt.so.1
#5 0xb78795ba in ?? () from /usr/lib/libxslt.so.1
#6 0x0812bdb8 in ?? ()
#7 0x08127100 in ?? ()
#8 0x08124b60 in ?? ()
#9 0x08108eb0 in ?? ()
#10 0x00000000 in ?? ()
Attached is the valgrind log from the crash. Hope this helps. All of
these are with the XSLT error logging patch you sent along previously.
--
John Krukoff <jkrukoff at ltgc.com>
Land Title Guarantee Company
-------------- next part --------------
==16392== Memcheck, a memory error detector.
==16392== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==16392== Using LibVEX rev 1732, a library for dynamic binary translation.
==16392== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==16392== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==16392== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==16392== For more details, rerun with: -v
==16392==
==16392== My PID = 16392, parent PID = 15505. Prog and args are:
==16392== python
==16392==
==16392== Invalid read of size 4
==16392== at 0x40153F0: (within /lib/ld-2.6.1.so)
==16392== by 0x4006337: (within /lib/ld-2.6.1.so)
==16392== by 0x4008217: (within /lib/ld-2.6.1.so)
==16392== by 0x40118C3: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392== by 0x4126245: _PyImport_GetDynLoadFunc (in /usr/lib/libpython2.5.so.1.0)
==16392== by 0x4113698: _PyImport_LoadDynamicModule (in /usr/lib/libpython2.5.so.1.0)
==16392== Address 0x44B5EE0 is 40 bytes inside a block of size 43 alloc'd
==16392== at 0x4022760: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16392== by 0x4007715: (within /lib/ld-2.6.1.so)
==16392== by 0x4008156: (within /lib/ld-2.6.1.so)
==16392== by 0x40118C3: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392== by 0x4126245: _PyImport_GetDynLoadFunc (in /usr/lib/libpython2.5.so.1.0)
==16392== by 0x4113698: _PyImport_LoadDynamicModule (in /usr/lib/libpython2.5.so.1.0)
==16392==
==16392== Invalid read of size 4
==16392== at 0x40153D9: (within /lib/ld-2.6.1.so)
==16392== by 0x4006337: (within /lib/ld-2.6.1.so)
==16392== by 0x4008217: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== Address 0x44B6244 is 20 bytes inside a block of size 22 alloc'd
==16392== at 0x4022760: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16392== by 0x40087B8: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392==
==16392== Invalid read of size 4
==16392== at 0x4015407: (within /lib/ld-2.6.1.so)
==16392== by 0x4006337: (within /lib/ld-2.6.1.so)
==16392== by 0x4008217: (within /lib/ld-2.6.1.so)
==16392== by 0x40118C3: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392== by 0x4126245: _PyImport_GetDynLoadFunc (in /usr/lib/libpython2.5.so.1.0)
==16392== by 0x4113698: _PyImport_LoadDynamicModule (in /usr/lib/libpython2.5.so.1.0)
==16392== Address 0x44CC434 is 76 bytes inside a block of size 79 alloc'd
==16392== at 0x4022760: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16392== by 0x4007715: (within /lib/ld-2.6.1.so)
==16392== by 0x4008156: (within /lib/ld-2.6.1.so)
==16392== by 0x40118C3: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392== by 0x4126245: _PyImport_GetDynLoadFunc (in /usr/lib/libpython2.5.so.1.0)
==16392== by 0x4113698: _PyImport_LoadDynamicModule (in /usr/lib/libpython2.5.so.1.0)
==16392==
==16392== Invalid read of size 4
==16392== at 0x4015407: (within /lib/ld-2.6.1.so)
==16392== by 0x4006337: (within /lib/ld-2.6.1.so)
==16392== by 0x4008217: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== Address 0x44CD144 is 12 bytes inside a block of size 15 alloc'd
==16392== at 0x4022760: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16392== by 0x40087B8: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392==
==16392== Invalid read of size 4
==16392== at 0x40153F0: (within /lib/ld-2.6.1.so)
==16392== by 0x4006337: (within /lib/ld-2.6.1.so)
==16392== by 0x4008217: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== Address 0x44CD4C8 is 24 bytes inside a block of size 25 alloc'd
==16392== at 0x4022760: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16392== by 0x40087B8: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392==
==16392== Invalid read of size 4
==16392== at 0x40153C3: (within /lib/ld-2.6.1.so)
==16392== by 0x4006337: (within /lib/ld-2.6.1.so)
==16392== by 0x4008217: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== Address 0x4D80A78 is 32 bytes inside a block of size 33 alloc'd
==16392== at 0x4022760: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16392== by 0x40087B8: (within /lib/ld-2.6.1.so)
==16392== by 0x400BF55: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x400C14F: (within /lib/ld-2.6.1.so)
==16392== by 0x401191E: (within /lib/ld-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x40112CD: (within /lib/ld-2.6.1.so)
==16392== by 0x41A6C4C: (within /lib/libdl-2.6.1.so)
==16392== by 0x400D891: (within /lib/ld-2.6.1.so)
==16392== by 0x41A70EB: (within /lib/libdl-2.6.1.so)
==16392== by 0x41A6B80: dlopen (in /lib/libdl-2.6.1.so)
==16392==
==16392== Invalid read of size 4
==16392== at 0x483853B: __pyx_f_4lxml_5etree__forwardError (lxml.etree.c:40855)
==16392== by 0x483879B: __pyx_f_4lxml_5etree__receiveXSLTError (lxml.etree.c:41371)
==16392== by 0x48DEEF8: xsltPrintErrorContext (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48DF090: xsltTransformError (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x4901433: xsltValueOf (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48FE5B9: (within /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48FEF5A: (within /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48FDFFA: xsltProcessOneNode (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x49034C9: (within /usr/lib/libxslt.so.1.1.24)
==16392== by 0x4903A46: xsltApplyStylesheetUser (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x4839B90: __pyx_f_4lxml_5etree_4XSLT__run_transform (lxml.etree.c:91598)
==16392== by 0x4853E42: __pyx_pf_4lxml_5etree_4XSLT___call__ (lxml.etree.c:90587)
==16392== Address 0x706D6F43 is not stack'd, malloc'd or (recently) free'd
==16392==
==16392== Process terminating with default action of signal 11 (SIGSEGV)
==16392== Access not within mapped region at address 0x706D6F43
==16392== at 0x483853B: __pyx_f_4lxml_5etree__forwardError (lxml.etree.c:40855)
==16392== by 0x483879B: __pyx_f_4lxml_5etree__receiveXSLTError (lxml.etree.c:41371)
==16392== by 0x48DEEF8: xsltPrintErrorContext (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48DF090: xsltTransformError (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x4901433: xsltValueOf (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48FE5B9: (within /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48FEF5A: (within /usr/lib/libxslt.so.1.1.24)
==16392== by 0x48FDFFA: xsltProcessOneNode (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x49034C9: (within /usr/lib/libxslt.so.1.1.24)
==16392== by 0x4903A46: xsltApplyStylesheetUser (in /usr/lib/libxslt.so.1.1.24)
==16392== by 0x4839B90: __pyx_f_4lxml_5etree_4XSLT__run_transform (lxml.etree.c:91598)
==16392== by 0x4853E42: __pyx_pf_4lxml_5etree_4XSLT___call__ (lxml.etree.c:90587)
==16392==
==16392== ERROR SUMMARY: 17 errors from 7 contexts (suppressed: 623 from 7)
==16392== malloc/free: in use at exit: 1,970,208 bytes in 3,841 blocks.
==16392== malloc/free: 11,248 allocs, 7,407 frees, 4,586,049 bytes allocated.
==16392== For counts of detected errors, rerun with: -v
==16392== searching for pointers to 3,841 not-freed blocks.
==16392== checked 2,393,756 bytes.
==16392==
==16392== LEAK SUMMARY:
==16392== definitely lost: 0 bytes in 0 blocks.
==16392== possibly lost: 27,020 bytes in 82 blocks.
==16392== still reachable: 1,943,188 bytes in 3,759 blocks.
==16392== suppressed: 0 bytes in 0 blocks.
==16392== Rerun with --leak-check=full to see details of leaked memory.
More information about the lxml-dev
mailing list