Printing out the objects stack

Fabiano Sidler fabianosidler at gmail.com
Sun Oct 29 18:48:40 CET 2006


Hi folks!

For getting a plan how a stack-based VM like Python works, I added a
function that prints out the current object stack. Unfortunately, it
crashes the VM. Could someone here take a look at it? What's wrong with
it?:

--- snip ---
static PyObject *
sys_stack(PyObject *self)
{
	PyFrameObject *f = PyThreadState_GET()->frame;
	PyObject
		**i,
		**begin = f->f_localsplus,
		**end = f->f_valuestack;
	
	end += f->f_code->co_stacksize;
	flog(	"co_name: %s\n"
		"co_stacksize: %d\n"
		"localsplus: %d\n"
		"valuestack: %d\n",
		PyString_AsString(f->f_code->co_name), f->f_code->co_stacksize,
		f->f_localsplus, f->f_valuestack);
	flog("locals:\n");
	{
		PyObject *list = f->f_code->co_names;
		int len,i;
		
		len = PyList_Size(list);
		for (i=0; i<len; i++) {
			PyObject *obi;
			char *strval;
			obi = PyList_GetItem(list, i);
			if ((obi=PyObject_Str(obi))!=NULL) {
				if ((strval=PyString_AsString(obi))!=NULL) {
					flog("[%d] %s\n", i, strval);
				}
			}
			Py_DECREF(obi);
		}
		Py_DECREF(list);
	}
	flog("end of locals\n");
	for (i=begin; i<=end; i++) {
		int o = ((int)f->f_valuestack - (int)i)/4;
		PyObject *obi;
		char *strval;
		
		if (*i == NULL) {
			flog("NULL\n");
			break; }
		if ((obi=PyObject_Str(*i)) != NULL) {
			if ((strval=PyString_AsString(obi)) != NULL) {
				flog("[%3d] %s\n", o, strval);
			}
		}
	}
	finished:
	Py_INCREF(Py_None);
	return Py_None;
}
--- snap ---

flog(fmt, ...) is my function to log to a file, sys_stack I've made available
to Python as sys.stack and PyFrame_New I modified so that it nulls the memory
allocated for the objects stack. Now the following Python code crashes...

--- snip ---
def f(foo,bar,boo,far):
	foobar='foobar'
	print foobar
	sys.stack()

f('foo','bar','boo','far') # CRASH
--- snap ---

...and in my "logfile" I have...

--- snip ---
co_name: f
co_stacksize: 1
localsplus: 136139316
valuestack: 136139336
locals:
end of locals
[  5] foo
[  4] bar
[  3] boo
[  2] far
[  1] foobar
[  0] <built-in function stack>
--- snap ---

Now the following things are not clear to me:
-Why does the VM crash? Did I use the wrong stack boundaries?
-Why are no locales printed?
-Why is the function "stack" not right before or after "foo"
 on the stack? When I disassemble the code of f with dis.dis,
 it reveals that sys.stack and foo are pushed onto the stack
 successively.

Greetings,
Fips



More information about the Python-list mailing list