Stack trace in C

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andre Poenitz

    #1

    Stack trace in C



    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_nam e
    # f = f.f_back
    #print "==="
    while tb:
    f = tb.tb_frame
    print f.f_lineno, f.f_code.co_nam e
    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::ostringstr eam msg;

    [...]
    #if 1
    // Branch 1
    PyObject * exc_type = 0;
    PyObject * exc_value = 0;
    PyObject * exc_traceback = 0;
    PyErr_Fetch(&ex c_type, &exc_value, &exc_traceback) ;
    PyObject * tb_frame = PyObject_GetAtt rString(exc_tra ceback, "tb_frame") ;
    #else
    // Branch 2
    PyObject * pName = PyString_FromSt ring("sys");
    PyObject * pModule = PyImport_Import (pName);
    PyObject * pFunc = PyObject_GetAtt rString(pModule , "exc_info") ;
    PyObject * pResult = PyObject_CallOb ject(pFunc, NULL);
    PyObject * tb_frame = PySequence_GetI tem(pResult, 2);
    #endif
    while (tb_frame != Py_None) {
    PyObject * f_code = PyObject_GetAtt rString(tb_fram e, "f_code");
    PyObject * f_lineno = PyObject_GetAtt rString(tb_fram e, "f_lineno") ;
    int lineno = PyInt_AsLong(f_ lineno);
    msg << " in line " << lineno << "\n";
    PyObject * tmp1 = PyObject_GetAtt rString(tb_fram e, "f_back");
    PyObject * tmp2 = PyObject_GetAtt rString(tb_fram e, "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'


Working...