durusmail: quixote-users: ptl core dump
ptl core dump
2001-11-06
2001-11-07
2001-11-07
ptl core dump
Greg Ward
2001-11-07
On 06 November 2001, Quinn Dunkan said:
> % cat >t.ptl
> a = [0,1]
> del a[0], a[1]
> ^D
> % python -c 'import quixote; quixote.enable_ptl(); import t'
> zsh: 18387 segmentation fault (core dumped)  python -c import quixote;
> quixote.enable_ptl(); import t
> % python
> Python 2.0 (#3, Jan 19 2001, 13:28:16)
> [GCC 2.95.2 19991024 (release)] on sunos5
> Type "copyright", "credits" or "license" for more information.
> >>>

Yes, I get a coredump as well, with Python 2.1.1.  This code should
raise IndexError; if I rename t.ptl to t.py and import it -- either with
or without PTL enabled -- it does so.  It's only if I import it as a PTL
module that the coredump happens.

Here's the top bit of the C traceback:

#0  eval_code2 (co=0x81568f0, globals=0x81a8234, locals=0x81a8234, args=0x0,
    argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0)
    at Python/ceval.c:1535
#1  0x8055799 in PyEval_EvalCode (co=0x81568f0, globals=0x81a8234,
    locals=0x81a8234) at Python/ceval.c:341
#2  0x805a864 in exec_statement (f=0x811bb88, prog=0x81568f0,
    globals=0x81a8234, locals=0x81a8234) at Python/ceval.c:3504
#3  0x8057480 in eval_code2 (co=0x81a8f48, globals=0x8167d94, locals=0x0,
    args=0x8143e30, argcount=3, kws=0x8143e3c, kwcount=0, defs=0x0,
    defcount=0, closure=0x0) at Python/ceval.c:1457
#4  0x8059bf4 in fast_function (func=0x819047c, pp_stack=0xbfffef64, n=3,
    na=3, nk=0) at Python/ceval.c:3022
#5  0x8058385 in eval_code2 (co=0x81a8f90, globals=0x8167d94, locals=0x0,
    args=0x80ec4a0, argcount=3, kws=0x80ec4ac, kwcount=0, defs=0x818f998,
    defcount=1, closure=0x0) at Python/ceval.c:1972
#6  0x8059bf4 in fast_function (func=0x81a51ec, pp_stack=0xbffff074, n=3,
    na=3, nk=0) at Python/ceval.c:3022

The relevant bit of ceval.c in Python 2.1.1 is:

    case UNPACK_SEQUENCE:
            v = POP();
            if (PyTuple_Check(v)) {                 <<<--- line 1535
                    if (PyTuple_Size(v) != oparg) {
                            PyErr_SetString(PyExc_ValueError,
                                     "unpack tuple of wrong size");
                            why = WHY_EXCEPTION;
                    }

The local variables here are:

  globals = (PyObject *) 0x81a13c8
  args = (PyObject **) 0x0
  stack_pointer = (PyObject **) 0x81a13c4
  next_instr = (unsigned char *) 0x81863cf "\177\002"
  opcode = 92
  oparg = 2
  why = WHY_NOT
  err = 0
  x = (PyObject *) 0x81a8234
  v = (PyObject *) 0x4                <<<--- BZZZZTT!!!
  w = (PyObject *) 0x80f0cc0
  u = (PyObject *) 0x81a8234
  t = (PyObject *) 0x0
  stream = (PyObject *) 0x0
  f = (PyFrameObject *) 0x81a1280
  fastlocals = (PyObject **) 0x81a13c8
  freevars = (PyObject **) 0x81a13c8
  retval = (PyObject *) 0x0
  tstate = (PyThreadState *) 0x80cdbf8
  first_instr = (unsigned char *) 0x81863a4 "\177"

So we're asking PyTuple_Check() to follow an *almost* NULL pointer.
It's close enough to NULL that it causes a segfault on Linux.

Note that this is related to tuple-unpacking; changing the code from
  del a[0], a[1]

to
  del a[0]
  del a[1]

works, ie. we get an IndexError on the second "del".

Looking at the language ref (sections 6.5 and 6.3), it sounds like
tuples shouldn't be involved here at all -- although "del a, b" *looks*
like a tuple, grammatically it isn't.  Not sure if that's true at the
implementation level, though.

Hmmm: if I make the code perfectly legal Python, eg.:
  a = [0,1]
  del a[0], a[0]
then it *still* dumps core as a PTL module.  So it's the
delete-multiple-items things that causes a problem, not
the delete-bogus-list-element.

Perhaps Quixote (specifically, quixote.ptl_compile) generates bad
bytecode in this case.  I've managed to disassemble t.ptlc, but I
haven't figured out how to disassemble t.pyc to compare the two.  Neil?

        Greg
--
Greg Ward - software developer                gward@mems-exchange.org
MEMS Exchange                            http://www.mems-exchange.org


reply