[Stackless] Stackless Digest, Vol 90, Issue 3
Christian Tismer
tismer at stackless.com
Fri Jul 8 13:34:07 CEST 2011
On 7/8/11 1:53 AM, Richard Tew wrote:
> On Thu, Jul 7, 2011 at 10:10 PM, Hussain Bohra
> <hussainbohra_30 at yahoo.com> wrote:
>> Hi Christian,
>>
>> Thanks for your feedback.
>>
>> Could you kindly let us know when you are done with the changes, so that we
>> can complete the existing tasks that are dependent on this fix.
> Can't you work around it? Like check if a frame is a cframe and skip
> it, if it is the case? I haven't looked at the traceback generation
> in detail, but I imagine that something along the following lines
> would work..
>
> lastTasklet = stackless.current
> thisTasklet = lastTasklet.next
> while True:
> thisFrame = thisTasklet.frame
> while thisFrame is not None:
> if not isinstance(thisFrame, stackless.cframe):
> # Do traceback related stuff.
> thisFrame = thisFrame.f_back
> thisTasklet = thisTasklet.next
> if lastTasklet is thisTasklet:
> break
Hi Richard, Hussain,
yes, I had a look now, and you are right. CFrames get into the way,
but are a small problem. Your workaround should be a simple quick
solution in the first place, and I encourage Hussain to try that first.
It is a really simple patch to traceback.py: insert a check into
extract_stack
before "if limit is None:":
while f and not isinstance(f, types.FrameType):
f = f.f_back
That should do.
---------------------------------------------
Now to the omission in stackless:
The special treatment of cframes is quite limited in stackless:
- sys._getframe has a patch to skip over anything that is no normal frame.
- frame objects have a getter function frame_getback() instead of the f_back
field.
The only way how the treatment of cframes might be circumvented
in extract_stack is when a cframe is given as an argument, and that
was the omission in stackless:
tasklet.frame exposes whatever it has to the user. Only for the running
tasklet, this gets redirected to the threadstate's frame, which in the
from python visible context never is a cframe.
The function slp_get_frame is the culprit (stackless_util.c):
/* CAUTION: This function returns a borrowed reference */
PyFrameObject *
slp_get_frame(PyTaskletObject *task)
{
PyThreadState *ts = PyThreadState_GET();
return ts->st.current == task ? ts->frame : task->f.frame;
}
This is correct for builtin API functions, but not for the python
interface. The getter methon tasklet_get_frame (taskletobject.c)
should skip over cframes.
static PyObject *
tasklet_get_frame(PyTaskletObject *task)
{
PyObject *ret = (PyObject*) slp_get_frame(task);
if (ret == NULL) ret = Py_None;
Py_INCREF(ret);
return ret;
}
I think something like the following should do it:
static PyObject *
tasklet_get_frame(PyTaskletObject *task)
{
PyFrameObject *f = (PyFrameObject *) slp_get_frame(task);
PyObject *ret;
while (f != NULL && !PyFrame_Check(f)) {
f = f_fback;
}
ret = (PyObject *) f;
if (ret == NULL) ret = Py_None;
Py_INCREF(ret);
return ret;
}
Not yet tested, but I guess that should do it.
Do you want to try when removing tasklet_become, or should I?
cheers -- chris
--
Christian Tismer :^)<mailto:tismer at stackless.com>
tismerysoft GmbH : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9A : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
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? http://www.stackless.com/
More information about the Stackless
mailing list