<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
<tt>This error exists since 2006. I think we introduced it on the<br>
Stackless sprint. I won't blame anybody, maybe it was me, no idea.<br>
<br>
In any case, the Stackless API is broken. PyEval_EvalFrame cannot<br>
be used.<br>
<br>
The code is working in the path<br>
<br>
<a class="moz-txt-link-abbreviated" href="mailto:svn+ssh://pythondev@svn.python.org/stackless/Python-2.4.2/src/Python/ceval.c">svn+ssh://pythondev@svn.python.org/stackless/Python-2.4.2/src/Python/ceval.c</a><br>
<br>
and broken in<br>
<br>
<a class="moz-txt-link-abbreviated" href="mailto:svn+ssh://pythondev@svn.python.org/stackless/Python-2.4.2/dev/Python/ceval.c">svn+ssh://pythondev@svn.python.org/stackless/Python-2.4.2/dev/Python/ceval.c</a><br>
<a class="moz-txt-link-abbreviated" href="mailto:svn+ssh://pythondev@svn.python.org/stackless/Python-2.4.3/dev/Python/ceval.c">svn+ssh://pythondev@svn.python.org/stackless/Python-2.4.3/dev/Python/ceval.c</a><br>
<br>
and all higher versions in branches, tags, and trunk of course.<br>
<br>
This means: nobody ever used the API explicitly since then, but me. :-)<br>
<br>
The reason why this is broken:<br>
In 2.4.2/src we had no retval parameter. It was a local, initialized to
NULL,<br>
but it was then initialized here:<br>
<br>
<font color="#3366ff">PyObject *<br>
PyEval_EvalFrame_value(PyFrameObject *f)<br>
{<br>
/* unfortunately we repeat all the variables here... */<br>
#ifdef DXPAIRS<br>
int lastopcode = 0;<br>
#endif<br>
register PyObject **stack_pointer; /* Next free slot in value
stack */<br>
register unsigned char *next_instr;<br>
register int opcode; /* Current opcode */<br>
register int oparg; /* Current opcode argument, if any */<br>
register enum why_code why; /* Reason for block stack unwind */<br>
register int err; /* Error status -- nonzero if error */<br>
register PyObject *x; /* Result object -- NULL if error */<br>
register PyObject *v; /* Temporary objects popped off stack */<br>
register PyObject *w;<br>
register PyObject *u;<br>
register PyObject *t;<br>
register PyObject *stream = NULL; /* for PRINT opcodes */<br>
register PyObject **fastlocals, **freevars;<br>
PyObject *retval = NULL; /* Return value */<br>
PyThreadState *tstate = PyThreadState_GET();<br>
PyCodeObject *co;<br>
<br>
/* when tracing we set things up so that<br>
<br>
not (instr_lb <= current_bytecode_offset <
instr_ub)<br>
<br>
is true when the line being executed has changed. The<br>
initial values are such as to make this false the first<br>
time it is tested. */<br>
int instr_ub = -1, instr_lb = 0, instr_prev = -1;<br>
<br>
unsigned char *first_instr;<br>
PyObject *names;<br>
PyObject *consts;<br>
#ifdef LLTRACE<br>
int lltrace;<br>
#endif<br>
#if defined(Py_DEBUG) || defined(LLTRACE)<br>
/* Make it easier to find out where we are with a debugger */<br>
char *filename;<br>
#endif<br>
<br>
fast_reentry:<br>
retval = tstate->st.tempval;<br>
tstate->st.tempval = NULL;<br>
#endif /* STACKLESS */<br>
<br>
co = f->f_code;</font><br>
<br>
The fast_reentry case vanished without any trace, therefore pushing<br>
the burden to initialize retval to the call-sites of<br>
PyEval_EvalFrame_Value. But this never happened. And it was not<br>
recognized because the function was only called indirectly<br>
via frame->f_execute, where a value is passed in.<br>
<br>
The correction would be to either make the NULL check more<br>
careful, or to pass in a dummy object which needs no reference.<br>
In any case, this is a necessary change to un-break the<br>
Stackless API.<br>
<br>
Nevertheless, and even worse, the API is broken even more.<br>
----------------------------------------------------------<br>
<br>
An API function that has no "slp" in it is never allowed to<br>
return the Py_UnwindToken.<br>
Exactly that is possible in the end of PyEval_EvalFrame_value:<br>
<br>
<font color="#00cccc"><font color="#3366ff">stackless_interrupt_call:<br>
<br>
f->f_execute = PyEval_EvalFrame_noval;<br>
f->f_stacktop = stack_pointer;<br>
<br>
/* the -1 is to adjust for the f_lasti change.<br>
(look for the word 'Promise' above) */<br>
f->f_lasti = INSTR_OFFSET() - 1;<br>
f = tstate->frame;<br>
return (PyObject *) Py_UnwindToken;<br>
#endif<br>
}</font><br>
<br>
</font>So the API needs a bit more protection, to really be compliant<br>
to the Python API.<br>
<br>
I came across this because I got into trouble when implementing<br>
Stackless support for Psyco. I think I can get along this by<br>
adding the necessary support functions to Psyco. This is easier<br>
right now than to consistently fix all Stackless versions.<br>
But the latter needs to be done, ASAP.<br>
<br>
cheers - chris<br>
<br>
On 4/12/10 8:36 PM, Christian Tismer wrote:</tt>
<blockquote cite="mid:4BC36827.90406@stackless.com" type="cite"><tt>There
appears to be a stackless error in release25-maint:
<br>
<br>
When I try to use the API call PyEval_EvalFrameEx, I always get
<br>
a crash, because PyEval_EvalFrameEx calls
<br>
PyEval_EvalFrameEx_slp, which does
<br>
<br>
return PyEval_EvalFrameEx_slp(f, throwflag, NULL);
<br>
<br>
This NULL value gets passed to
<br>
<br>
return PyEval_EvalFrame_value(f, throwflag, retval);
<br>
<br>
and then retval is checked: stacklesseval.c#692
<br>
<br>
/* always check for an error flag */
<br>
if (retval == NULL) {
<br>
why = WHY_EXCEPTION;
<br>
goto on_error;
<br>
}
<br>
<br>
This cannot be correct, it must be possible to enter the evaluator
<br>
with a NULL retval. Semantically it originates from a local variable
<br>
which is initialized as NULL, so somehow the above test must be
<br>
misplaced.
<br>
<br>
This blocks me at the moment because I'm confused how this error
<br>
crept in; suffering too many versions in the moment.
<br>
<br>
help - chris
<br>
<br>
</tt>
</blockquote>
<tt><br>
</tt><br>
<pre class="moz-signature" cols="72">--
Christian Tismer :^) <a class="moz-txt-link-rfc2396E" href="mailto:tismer@stackless.com"><mailto:tismer@stackless.com></a>
tismerysoft GmbH : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9A : *Starship* <a class="moz-txt-link-freetext" href="http://starship.python.net/">http://starship.python.net/</a>
14109 Berlin : PGP key -> <a class="moz-txt-link-freetext" href="http://wwwkeys.pgp.net/">http://wwwkeys.pgp.net/</a>
work +49 30 802 86 56 mobile +49 173 24 18 776 fax +49 30 80 90 57 05
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? <a class="moz-txt-link-freetext" href="http://www.stackless.com/">http://www.stackless.com/</a></pre>
</body>
</html>