Accessing a Python traceback from the C API

This is an old question but for future reference, you can get the current stack frame from the thread state object and then just walk the frames backward. A traceback object isn’t necessary unless you want to preserve the state for the future.

For example:

PyThreadState *tstate = PyThreadState_GET();
if (NULL != tstate && NULL != tstate->frame) {
    PyFrameObject *frame = tstate->frame;

    printf("Python stack trace:\n");
    while (NULL != frame) {
        // int line = frame->f_lineno;
        /*
         frame->f_lineno will not always return the correct line number
         you need to call PyCode_Addr2Line().
        */
        int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
        const char *filename = PyString_AsString(frame->f_code->co_filename);
        const char *funcname = PyString_AsString(frame->f_code->co_name);
        printf("    %s(%d): %s\n", filename, line, funcname);
        frame = frame->f_back;
    }
}

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)