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