How to Get the Crash Errors When Embedding
Howard Lightstone
howard at eegsoftware.com
Wed Sep 12 12:22:29 EDT 2001
Spam Hater wrote:
> Hi All,
>
> I'm happily writing an app that embeds a python
> interpreter within a graphical C program.
>
> My big problem for me is that when I have a python
> interpreter exception, I can't see the stack dump.
>
> I've redirected sys.stderr and sys.stdout such that
> errors should show up in a log file. And they do, in
> fact, if I run my Python script through the command
> line interpreter. But NOT when I run the surrounding
> 'C' program.
>
> Yeah, I can write little test command line scripts to
> try and cause problems to happen, but this doesn't
> always help me track down 'insitu' problems and gets
> quite tedious.
>
> Any help greatly appreciated! --matt
>
> __________________________________________________
> Do You Yahoo!?
> Get email alerts & NEW webcam video instant messaging with Yahoo! Messenger
> http://im.yahoo.com
Well, below is what I use. It captures stdout/stderr and routes them to a
separate Tkinter window which is created if needed. When the program exits, if
the separate window exists, it waits until that window is closed to 'really'
exit (so you can read the contents).
To use, import DebugWin and call DebugWin.Take_all() before doing anything
else.
"""
#DebugWin.py
Pseudo debug screens
These capture stderr/std and route them to a Tkinter text widget.
This implementation uses a common window for stdout/stderr with
an asterisk at the beginning of each stderr line.
"""
import Tkinter
import sys,string
class DbgText:
Dbgtopwin=None
Dbgwidget=None
DbgRoot=None
def _kill_topwin(self):
DbgText.Dbgwidget=None
if DbgText.Dbgtopwin != None:
DbgText.Dbgtopwin.destroy()
DbgText.Dbgtopwin=None
def __init__(self,kind=''):
self.kind=kind
self.window=None
self.widget=None
self.called=0
self.hide=0
self.buffer=''
def __del__(self):
"On deletion, wait for user to see the output"
if DbgText.Dbgtopwin != None:
See()
self._kill_topwin()
def write(self,charstr):
"write text to buffer or window"
if self.hide:
self.buffer.append(charstr)
else:
if self.window == None:
if DbgText.Dbgtopwin == None:
DbgText.Dbgtopwin=Tkinter.Tk()
DbgText.Dbgtopwin.protocol('WM_DELETE_WINDOW',Dbg_kill_topwin)
DbgText.Dbgwidget=Tkinter.Text(DbgText.Dbgtopwin)
DbgText.Dbgwidget.pack(expand=1)
top=DbgText.Dbgtopwin
wid=DbgText.Dbgwidget
else:
if self.widget == None:
self.widget=Tkinter.Text(self.window)
top=self.window
wid=self.widget
if self.kind != '':
ep=wid.index('end')
sp=string.split(ep,'.')
# determine length of 'previous' line
prevl=int(sp[0])
tx='\n'
if prevl:
pl='%d.0' % (prevl-1)
tx=wid.get(pl,ep)
# if this is start of a new line
if tx[0] == '\n':
wid.insert('end',self.kind)
wid.insert('end',charstr)
self.called=1
top.update()
def Dbg_kill_topwin():
f=DbgText()
f._kill_topwin()
def Take_stdout():
"DIsplay stdout in text widget"
if not isinstance(sys.stdout,DbgText):
f=DbgText()
f.prev=sys.stdout
sys.stdout=f
def Take_stderr():
"DIsplay stderr in text widget"
if not isinstance(sys.stderr,DbgText):
f=DbgText('*')
f.prev=sys.stderr
sys.stderr=f
def Restore_stdout():
f=sys.stdout
if isinstance(f,DbgText):
sys.stdout=f.prev
del f
def Restore_stderr():
f=sys.stderr
if isinstance(f,DbgText):
sys.stderr=f.prev
del f
def Define_Root():
root=Tkinter.Tk()
root.withdraw()
DbgText.DbgRoot=root
def See():
db=DbgText()
if db.Dbgtopwin != None:
db.Dbgtopwin.mainloop() # loop for me to see
def Take_all():
"send stderr/stdout to Tkinter text window/widget"
Take_stdout()
Take_stderr()
def Restore_all():
"restore stderr/stdout"
Restore_stdout()
Restore_stderr()
if __name__ == '__main__':
print 'stdout is here'
Take_stdout()
print 'stdout should now be in window'
print ' this is the second line'
raw_input()
Restore_stdout()
print 'stdout back to original'
More information about the Python-list
mailing list