A
Andre Poenitz
Bear with me - I am new to Python. (And redirect me to a more suitable
newsgroup in case this one is not appropriate.)
I am trying to embed Python into a C++ application and want to get back
a backtrace in case of errors in the python code.
This works well with e.g.
import sys
def u3():
xxxxxx() # raise an error
def u2():
u3()
def u1():
u2()
def f():
try:
u1()
except NameError:
type, value, tb = sys.exc_info()
#f = tb.tb_frame
#while f:
# print f.f_lineno, f.f_code.co_name
# f = f.f_back
#print "==="
while tb:
f = tb.tb_frame
print f.f_lineno, f.f_code.co_name
tb = tb.tb_next
def d1():
f()
def d2():
d1()
d2()
on the python side.
However, I want to do that on the C side.
So far I have code similar to
std:stringstream msg;
[...]
#if 1
// Branch 1
PyObject * exc_type = 0;
PyObject * exc_value = 0;
PyObject * exc_traceback = 0;
PyErr_Fetch(&exc_type, &exc_value, &exc_traceback);
PyObject * tb_frame = PyObject_GetAttrString(exc_traceback, "tb_frame");
#else
// Branch 2
PyObject * pName = PyString_FromString("sys");
PyObject * pModule = PyImport_Import(pName);
PyObject * pFunc = PyObject_GetAttrString(pModule, "exc_info");
PyObject * pResult = PyObject_CallObject(pFunc, NULL);
PyObject * tb_frame = PySequence_GetItem(pResult, 2);
#endif
while (tb_frame != Py_None) {
PyObject * f_code = PyObject_GetAttrString(tb_frame, "f_code");
PyObject * f_lineno = PyObject_GetAttrString(tb_frame, "f_lineno");
int lineno = PyInt_AsLong(f_lineno);
msg << " in line " << lineno << "\n";
PyObject * tmp1 = PyObject_GetAttrString(tb_frame, "f_back");
PyObject * tmp2 = PyObject_GetAttrString(tb_frame, "tb_next");
// Now, neither tmp1 nor tmp2 is usable
// tb_frame = tmpX;
}
}
[Plus some reference counting/error checking code I left out]
The 'Branch 1' version works for a sinmgle frame, but then tmp1 will be
None and tmp2 0 at the end of the iteration and so no further frames
are found.
The 'Branch 2' version creates immediatly tb_frame as None and
does not even enter the loop body once.
So what am I doing wrong? How do I get the equivalent of the python
code in C?
Andre'
newsgroup in case this one is not appropriate.)
I am trying to embed Python into a C++ application and want to get back
a backtrace in case of errors in the python code.
This works well with e.g.
import sys
def u3():
xxxxxx() # raise an error
def u2():
u3()
def u1():
u2()
def f():
try:
u1()
except NameError:
type, value, tb = sys.exc_info()
#f = tb.tb_frame
#while f:
# print f.f_lineno, f.f_code.co_name
# f = f.f_back
#print "==="
while tb:
f = tb.tb_frame
print f.f_lineno, f.f_code.co_name
tb = tb.tb_next
def d1():
f()
def d2():
d1()
d2()
on the python side.
However, I want to do that on the C side.
So far I have code similar to
std:stringstream msg;
[...]
#if 1
// Branch 1
PyObject * exc_type = 0;
PyObject * exc_value = 0;
PyObject * exc_traceback = 0;
PyErr_Fetch(&exc_type, &exc_value, &exc_traceback);
PyObject * tb_frame = PyObject_GetAttrString(exc_traceback, "tb_frame");
#else
// Branch 2
PyObject * pName = PyString_FromString("sys");
PyObject * pModule = PyImport_Import(pName);
PyObject * pFunc = PyObject_GetAttrString(pModule, "exc_info");
PyObject * pResult = PyObject_CallObject(pFunc, NULL);
PyObject * tb_frame = PySequence_GetItem(pResult, 2);
#endif
while (tb_frame != Py_None) {
PyObject * f_code = PyObject_GetAttrString(tb_frame, "f_code");
PyObject * f_lineno = PyObject_GetAttrString(tb_frame, "f_lineno");
int lineno = PyInt_AsLong(f_lineno);
msg << " in line " << lineno << "\n";
PyObject * tmp1 = PyObject_GetAttrString(tb_frame, "f_back");
PyObject * tmp2 = PyObject_GetAttrString(tb_frame, "tb_next");
// Now, neither tmp1 nor tmp2 is usable
// tb_frame = tmpX;
}
}
[Plus some reference counting/error checking code I left out]
The 'Branch 1' version works for a sinmgle frame, but then tmp1 will be
None and tmp2 0 at the end of the iteration and so no further frames
are found.
The 'Branch 2' version creates immediatly tb_frame as None and
does not even enter the loop body once.
So what am I doing wrong? How do I get the equivalent of the python
code in C?
Andre'