Print traceback in C code

Mark Hammond mhammond at skippinet.com.au
Thu Feb 6 17:17:33 EST 2003


Thomas Heller wrote:
> I'm trying to print a traceback in C code.
> 
> According to some articles I found, mainly by Mark Hammond, it's
> basically that I would have to write something like this in C
> 
>   import traceback, StringIO
>   s = StringIO.StringIO()
>   traceback.print_exception(tb_type, tb_value, tb_traceback, file=s)
> 
> and then call s.get_value() and convert it to a string.
> I'm stuck, however, because calling
> 
>   PyErr_Fetch(&tb_type, &tb_value, &tb_traceback);
> 
> leaves a NULL pointer in tb_traceback, although tb_type and tb_value
> are Python objects. Even calling PyErr_NormalizeException() doesn't
> help.
> 

I believe that the traceback is setup by the exception handling code in 
Python popping out the stack frames.  A traceback is from the "current 
frame" to the frame causing the error, and obviously the depth of this 
changes as exception handlers at different levels are walked.

So, if your C code is setting an exception, then trying to print it, 
there is no traceback available.  However, if your C code called into 
Python, and Python returned NULL indicating an exception, then Python 
will have set the traceback up as a result of the normal processing that 
returned control to your code from the API.

If all you want to do is walk the stack from your C code (and was hoping 
an exception+traceback would show this for you), then look at 
sys._getframe().  From the Pythonwin interactive window:

 >>> f=sys._getframe()
 >>> print f.f_code.co_filename, f.f_lineno
<interactive input> 1
 >>> f=f.f_back
 >>> print f.f_code.co_filename, f.f_lineno
E:\src\pythonex\pythonwin\pywin\framework\interact.py 261
 >>> f=f.f_back
 >>> print f.f_code.co_filename, f.f_lineno
E:\src\python-cvs\lib\code.py 88
 >>>


Mark.





More information about the Python-list mailing list