GPF only on exit program using System Menu

Hi,

I got GPF on Windows 2000 when exiting from my program *using* the system menu close ( either 'x' button or double-clicking the system menu or alt-f4)

When I use my own Exit button that simply calls self.Close() on the wxFrame derivative class, the program exits normally.

I have narrowed that GPF only happens if I have a wxGrid that is "hooked up" to an ODBC table (MSDE database). By "hooked up", I mean you'll find things like:

class DataAwareTableBase(wxPyGridTableBase):

    def __init__(self, grid, tableName):
        wxPyGridTableBase.__init__(self)
        self.grid = grid
        self.conn = s_getNewConnection()
        table = Table(self.conn, tableName)
        self.browse = Browse(self.conn, table, None, None)

    def GetNumberRows(self):
        return self.browse.get_rowcount()

    def GetNumberCols(self):
        return self.browse.get_colcount()

    def IsEmptyCell(self, row, col):
        return false

    def GetValue(self, row, col): <====== This populates the grid with the data from the cursor
        return self.browse.getval(row, col)

    def SetValue(self, row, col, value):
        print 'SetValue(%s, %d, %d, "%s") ignored' % (self.grid.tableName, row, col, value)

    def GetColLabelValue(self, idx):
        header = self.browse.get_coldesc()[idx]
        return header[0]

where self.browse is another class that has the live cursors to the odbc data source.
I tried to clean things up (close and deallocate the cursors, destroy the grids, etc.) on EVT_CLOSE of the wxFrame, but somehow wxpython keeps executing wxGrid events after the objects are destroyed.

Or so it seems, looking at dr watson log that looks like this:

State Dump for Thread Id 0x420

eax=00fecc01 ebx=00000000 ecx=0101a550 edx=0097c5a0 esi=01013a88 edi=10010f10
eip=00000000 esp=0012efe4 ebp=00761030 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000206

function: <nosymbols>
FAULT ->00000000 ???
        00000001 ???
        00000002 ???
        00000003 ???

*----> Stack Back Trace <----*

FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 Function Name
0012EFE0 00B2B16B 00000001 10010F10 01013A88 01241709 !<nosymbols>
00761030 1E0D7328 00000000 00000000 00000016 1E0CF840 !wxGrid::~wxGrid
00002548 00000000 00000000 00000000 00000000 00000000 !PyTuple_Type

What puzzles me is that this doesn't happen if I call self.Close() on the wxFrame directly.
Please help!

Will Gunadi

Will Gunadi wrote:

Hi,

I got GPF on Windows 2000 when exiting from my program *using* the system menu close ( either 'x' button or double-clicking the system menu or alt-f4)

When I use my own Exit button that simply calls self.Close() on the wxFrame derivative class, the program exits normally.

I have narrowed that GPF only happens if I have a wxGrid that is "hooked up" to an ODBC table (MSDE database). By "hooked up", I mean you'll find things like:

class DataAwareTableBase(wxPyGridTableBase):

    def __init__(self, grid, tableName):
        wxPyGridTableBase.__init__(self)
        self.grid = grid
        self.conn = s_getNewConnection()
        table = Table(self.conn, tableName)
        self.browse = Browse(self.conn, table, None, None)
     def GetNumberRows(self):
        return self.browse.get_rowcount()

    def GetNumberCols(self):
        return self.browse.get_colcount()

    def IsEmptyCell(self, row, col):
        return false

    def GetValue(self, row, col): <====== This populates the grid with the data from the cursor
        return self.browse.getval(row, col)

    def SetValue(self, row, col, value):
        print 'SetValue(%s, %d, %d, "%s") ignored' % (self.grid.tableName, row, col, value)
            def GetColLabelValue(self, idx):
        header = self.browse.get_coldesc()[idx]
        return header[0]

where self.browse is another class that has the live cursors to the odbc data source.
I tried to clean things up (close and deallocate the cursors, destroy the grids, etc.) on EVT_CLOSE of the wxFrame, but somehow wxpython keeps executing wxGrid events after the objects are destroyed.

Or so it seems, looking at dr watson log that looks like this:

One thing to be aware of is that for top level windows calling Destroy (or calling event.Skip from the EVT_CLOSE handler) does not cause the frame to be deleted immediately, but it will happen the next time the idle events are processed. This is so it can still respond to any pending events.

So what you may want to do is set a isBeingClosed flag in your EVT_CLOSE handler that your grid table checks before doing anything with the database.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!