471,350 Members | 1,699 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,350 software developers and data experts.

Getting error message/trace over the C API

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
Oct 16 '07 #1
3 3053
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

Oct 16 '07 #2
Sami Vaisanen <en********@hotmail.comwrote:
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.
Oct 16 '07 #3
On Tue, 16 Oct 2007 18:55:22 +0000, Duncan Booth wrote:
Sami Vaisanen <en********@hotmail.comwrote:
>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

Oct 18 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

10 posts views Thread by Brian Conway | last post: by
3 posts views Thread by Sean | last post: by
1 post views Thread by thangchan | last post: by
reply views Thread by XIAOLAOHU | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.