Getting error message/trace over the C API

Discussion in 'Python' started by Sami Vaisanen, Oct 16, 2007.

  1. Hello group,

    I'm writing a C++ based application that embeds the python engine. Now I
    have a problem regarding exception/error information. Is there a way to
    get the exception message and possibly the traceback into a string for
    example? I've been eyeballing the PyErr_ module and it seems fairly
    limited. In other words PyErr_Print() calls the right functions for
    getting the exception information but unfortunately it is hardwired to
    print this data directly into sys.stderr, and for an embedded application
    this is completely inappropriate.

    I have seen solutions that propose writing a custom Python class with
    write method and using that to grab the output from sys.stderr and then
    saving the data for example into a variable for later access, but unless
    Im mistaken this solution (not only that it is extremely ugly) is not
    thread safe. Even if a thread in my application is holding GIL, the lock
    can be released by extensions/the interpreter and thus opens up a race
    condition regarding that grabber object.

    Please advice how to do this.

    -sami
    Sami Vaisanen, Oct 16, 2007
    #1
    1. Advertising

  2. Sami Vaisanen schrieb:
    > Hello group,
    >
    > I'm writing a C++ based application that embeds the python engine. Now I
    > have a problem regarding exception/error information. Is there a way to
    > get the exception message and possibly the traceback into a string for
    > example? I've been eyeballing the PyErr_ module and it seems fairly
    > limited. In other words PyErr_Print() calls the right functions for
    > getting the exception information but unfortunately it is hardwired to
    > print this data directly into sys.stderr, and for an embedded application
    > this is completely inappropriate.
    >
    > I have seen solutions that propose writing a custom Python class with
    > write method and using that to grab the output from sys.stderr and then
    > saving the data for example into a variable for later access, but unless
    > Im mistaken this solution (not only that it is extremely ugly) is not
    > thread safe. Even if a thread in my application is holding GIL, the lock
    > can be released by extensions/the interpreter and thus opens up a race
    > condition regarding that grabber object.


    You should call 'import traceback; traceback.format_exc()' from your C code;
    it returns a string (a 'PyObject *' that contains a string).

    Thomas
    Thomas Heller, Oct 16, 2007
    #2
    1. Advertising

  3. Sami Vaisanen

    Duncan Booth Guest

    Sami Vaisanen <> wrote:

    > Hello group,
    >
    > I'm writing a C++ based application that embeds the python engine. Now I
    > have a problem regarding exception/error information. Is there a way to
    > get the exception message and possibly the traceback into a string for
    > example? I've been eyeballing the PyErr_ module and it seems fairly
    > limited. In other words PyErr_Print() calls the right functions for
    > getting the exception information but unfortunately it is hardwired to
    > print this data directly into sys.stderr, and for an embedded application
    > this is completely inappropriate.
    >
    >
    > Please advice how to do this.
    >

    All you have to do is call whatever functions you would call from Python.
    e.g. from C you need to import traceback, then call getattr to get the
    appropriate function (e.g. format_exc or format_exception), then just call
    it.
    Duncan Booth, Oct 16, 2007
    #3
  4. On Tue, 16 Oct 2007 18:55:22 +0000, Duncan Booth wrote:

    > Sami Vaisanen <> wrote:
    >
    >> Hello group,
    >>
    >> I'm writing a C++ based application that embeds the python engine. Now I
    >> have a problem regarding exception/error information. Is there a way to
    >> get the exception message and possibly the traceback into a string for
    >> example? I've been eyeballing the PyErr_ module and it seems fairly
    >> limited. In other words PyErr_Print() calls the right functions for
    >> getting the exception information but unfortunately it is hardwired to
    >> print this data directly into sys.stderr, and for an embedded application
    >> this is completely inappropriate.
    >>
    >>
    >> Please advice how to do this.
    >>

    > All you have to do is call whatever functions you would call from Python.
    > e.g. from C you need to import traceback, then call getattr to get the
    > appropriate function (e.g. format_exc or format_exception), then just call
    > it.




    void get_python_exception(string& message, string& traceback)
    {
    GIL g;

    PyObject* type = NULL;
    PyObject* value = NULL;
    PyObject* trace = NULL;

    PyErr_Fetch(&type, &value, &trace);

    py_ref ref_type(type);
    py_ref ref_value(value);
    py_ref ref_trace(trace);

    py_ref name(PyString_FromString("traceback"));
    py_ref module(PyImport_Import(name.get()));
    if (module)
    {
    py_ref fun(PyObject_GetAttrString(module.get(), "format_exc"));
    if (fun)
    {
    PyErr_Restore(type, value, trace);
    ref_type.release();
    ref_value.release();
    ref_trace.release();

    py_ref ret(PyObject_CallObject(fun.get(), NULL));
    if (ret && PyString_Check(ret.get()))
    {
    char* str = PyString_AsString(ret.get());
    message = str;
    traceback = "traceback not available";
    return;
    }
    }
    }
    message = "message not available";
    traceback = "traceback not available";
    }

    str evaluates to "None", any ideas what gives here? I've also tried to
    call the traceback with a different function, such as
    PyObject_CallFunctionObjArgs but the result is still same.

    Thanks
    Sami Vaisanen, Oct 18, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rukmal Fernando
    Replies:
    4
    Views:
    828
    Richard Grimes [MVP]
    Oct 27, 2003
  2. Matthias S.
    Replies:
    1
    Views:
    617
    Daniel Fisher\(lennybacon\)
    Nov 30, 2005
  3. Jiho Han
    Replies:
    0
    Views:
    487
    Jiho Han
    Aug 22, 2006
  4. =?Utf-8?B?RGF2aWQgVGhpZWxlbg==?=

    Adding my messages to the trace.axd trace?

    =?Utf-8?B?RGF2aWQgVGhpZWxlbg==?=, Apr 6, 2007, in forum: ASP .Net
    Replies:
    3
    Views:
    567
    =?Utf-8?B?RGF2aWQgVGhpZWxlbg==?=
    Apr 6, 2007
  5. Chris Newby
    Replies:
    0
    Views:
    750
    Chris Newby
    Jul 28, 2008
Loading...

Share This Page