[wxPython] Non-deterministic crash on exit on Win32 (but not Linux)

Hi,

I'm writing a medium-sized application in wxPython (see
myparo.sourceforge.net) and so far, everything's working fine
and it's running on both Linux and Win32.

However, recently I've been experiencing this weird problem
where the application will crash while exiting on Win32.
Here's the facts so far:
        - Win32 config: Win98, BeOpen Python 2.0, wxPython-2.2.5,
          Win32-all extensions from ActiveState
        - Crashes *only* on exit (i.e., when top-level frame closes)
        - Seems to be non-deterministic, I can't seem to come up
          with a test case that crashes all the time
        - The fault itself is either an invalid instruction or
          an invalid page fault in either the Python DLL or
          the wxPython DLL (again, apparently non-deterministic
          choice between which DLL to crash in)
        - Runs fine when I execute it in the Python debugger!!
        - Runs fine on Linux

I know this might not really help in narrowing down the problem
but it would be great to get some tips on where I can start
looking to see what I'm doing wrong ...

Y.

···

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I know this might not really help in narrowing down the problem

Without more info it's really hard to say.

but it would be great to get some tips on where I can start
looking to see what I'm doing wrong ...

If you can consistenly duplicate it then it would probably be easy to figure
out, or at least narrow it down to the offending code that you could then
send me.

Try running your app in little segments, exiting between each one. If you
can't duplicate it then systematically build up your segments until you find
one that fails.

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

OK, I'll try doing this.

    BTW, is there some way to get a stack trace on a crash in Windows?
    On a Unix box, I could use a debugger to inspect a core dump but
    Windows only seems to display the PC and registers. Is it
    possible to run a wxPython app in the MSVC++ debugger and get a
    stack trace when it crashes?
    
    Y.

···

On Wednesday, February 14, 2001 at 10:40:15 PM, Robin Dunn wrote:

but it would be great to get some tips on where I can start
looking to see what I'm doing wrong ...

If you can consistenly duplicate it then it would probably be easy to figure
out, or at least narrow it down to the offending code that you could then
send me.

Try running your app in little segments, exiting between each one. If you
can't duplicate it then systematically build up your segments until you find
one that fails.

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

OK, I finally managed to narrow down the crash problem I was
    having down to some weird interaction between a tree and a
    list (controls). I've appended ~50 lines of Python that
    reproduces the problem. If you run it, you should get
    a splitter window with a tree on the left and a list on
    the right (like Windows Explorer). The basic idea (in my
    original app) is that the tree represents your MP3 collection
    organized by (say) artist and album while the list will show
    all the songs in the currently selected artist or album.

    So the problem comes when you run the example below and then exit:
    If you click on "All music" and then exit, then everything's fine.
    If you click on "Artist" and then exit, I get a Python or
    wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
    wxPython 2.2.5.

    The weird thing is that the crash doesn't happen if I use
    the tree by itself or the list by itself. It has to be the
    two of them paired together.

    Anyone have any bright ideas?

    Thanks,
    Y.

# ------------- BEGIN SAMPLE CODE ----------------------
from wxPython.wx import *

class MP3List(wxListCtrl):
    def __init__( self, parent ):
        wxListCtrl.__init__( self, parent, wxNewId() )
        
    def Set_contents( self, song_list ):
        self.ClearAll()
        for row_num in range( len(song_list) ):
            self.InsertStringItem( row_num, song_list[row_num] )
        
class RepositoryTree(wxTreeCtrl):
    def __init__(self, parent, list_win ):
        wxTreeCtrl.__init__( self, parent, wxNewId() )
        self.list_window = list_win
        EVT_TREE_SEL_CHANGED( self, self.GetId(), self.On_selection_change )
        
    def Set_contents( self ):
        self.root = self.AddRoot( "All music" )
        self.artist_index = self.AppendItem( self.root, "Artist" )
        self.Expand( self.root )

    def On_selection_change( self, event ):
        self.list_window.Set_contents( ["Song"] )
    
class Repository(wxSplitterWindow):
    def __init__(self, parent):
        wxSplitterWindow.__init__( self, parent, -1 )
        
        self.list_window = MP3List( self )
        self.tree_window = RepositoryTree( self, self.list_window )
        self.tree_window.Set_contents()

        self.SplitVertically( self.tree_window, self.list_window )
        self.SetMinimumPaneSize( 100 )
        self.SetSashPosition( 150 )

class ParoFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__( self, parent, id, title )
        self.repository_win = Repository( self )

    def OnCloseWindow( self, event ):
        self.Destroy()

class ParoApp(wxApp):
    def OnInit( self ):
        self.frame = ParoFrame( NULL, -1, "MyParo" )
        self.frame.Show( TRUE )
        self.SetTopWindow( self.frame )
        return TRUE

paro_instance = ParoApp(0)
paro_instance.MainLoop()
# ------------- END SAMPLE CODE ----------------------

···

On Wednesday, February 14, 2001 at 10:40:15 PM, Robin Dunn wrote:

If you can consistenly duplicate it then it would probably be easy to figure
out, or at least narrow it down to the offending code that you could then
send me.

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

This is my first try with wxPython, and I haven't done
a lot of GUI programming (just GUI 'painting') before.

I thought I'd make a little calculator, and thus I made
buttons with digits etc. These all call a frame method
self.OnPressMe through EVT_BUTTON.

Then my thought was that OnPressMe(self, event) should
figure out which button was pressed, and then know
what to do.

I could obviously make one call-back function for
each button, but I got this idea that I would be able
to use the text on the button and 'eval' to basically
make this program without coding...

So, how does OnPressMe figure out which button was
pressed?

/Magnus

Sorry, no suggestions, but I did try it under Linux RH6.2,
wxWindows 2.2.5, BeOpen 2.0 and it didn't crash after clicking on
Artist and exiting. I also tried clicking on All music
and Song and exiting, no problems, exit code 0.

  Rob Cakebread

p.s. The screenshots for MyParo look excellent, can't wait.

Quoting Yumpee <terabaap@users.sourceforge.net>:

···

    So the problem comes when you run the example below and then exit:
    If you click on "All music" and then exit, then everything's fine.
    If you click on "Artist" and then exit, I get a Python or
    wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
    wxPython 2.2.5.

--------------------------------------
FREE ANONYMOUS EMAIL! Sign up now.
http://www.subdimension.com/freemail

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

    So the problem comes when you run the example below and then exit:
    If you click on "All music" and then exit, then everything's fine.
    If you click on "Artist" and then exit, I get a Python or
    wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
    wxPython 2.2.5.

It doesn't crash here (on Win2k.) Nothing in the code is jumping out at me
as being wrong either.

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Any chance of a Win98 user on this list reproducing my problem.
    I've got crashes with this code on two different Win98 boxes
    with BeOpen Python 2.0 and wxPython 2.2.2 and 2.2.5. It's not
    a complete show-stopper for me, but it's irritating enough
    that I'd like to know what the problem is.
    
    Y.

···

On Monday, February 19, 2001 at 12:03:59 AM, Robin Dunn wrote:

    So the problem comes when you run the example below and then exit:
    If you click on "All music" and then exit, then everything's fine.
    If you click on "Artist" and then exit, I get a Python or
    wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
    wxPython 2.2.5.

It doesn't crash here (on Win2k.) Nothing in the code is jumping out at me
as being wrong either.

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I just tested your program briefly on my Windows 98 machine--not with Python
2.0 but with 1.5.2 (I haven't got around to upgrading yet--am fairly sure
some critical error-handling code will need some more work... in time...)

    OK, I finally managed to narrow down the crash problem I was
    having down to some weird interaction between a tree and a
    list (controls). I've appended ~50 lines of Python that
    reproduces the problem. If you run it, you should get
    a splitter window with a tree on the left and a list on
    the right (like Windows Explorer). The basic idea (in my
    original app) is that the tree represents your MP3 collection
    organized by (say) artist and album while the list will show
    all the songs in the currently selected artist or album.

    So the problem comes when you run the example below and then exit:
    If you click on "All music" and then exit, then everything's fine.
    If you click on "Artist" and then exit, I get a Python or
    wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
    wxPython 2.2.5.

It doesn't crash for me. When I get around to installing Python 2 I'll test
it again, but that won't be this week I think, and uninstalling my current
version is too risky for me, at the moment...

Oh, and I'm still using wxPython 2.2.2(according to CHANGES.txt)...

Chris

···

-------------------------------------------------------------------------
Chris Fama <mailto:Chris.Fama@whollysnakes.com> Phone:(07) 3870 5639
Brisbane, Australia Mobile:(0400) 833 700
-------------------------------------------------------------------------
....
I am haunted by numberless islands, and many a Danaan shore,
Where Time would surely forget us, and Sorrow come near us no more;
Soon far from the rose and the lily and fret of the flames would we be,
Were we only white birds, my beloved, buoyed out on the foam of the sea!
from THE WHITE BIRDS by William Butler Yeats

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Yes, it crashes on Win98SE, BeOpen Python 2.0, wxPython 2.2.5 for me.
No crash on Linux, Python 2.0, wxPython 2.2.5

···

At 06:11 AM 2/19/01 -0600, you wrote:

On Monday, February 19, 2001 at 12:03:59 AM, Robin Dunn wrote:
>> So the problem comes when you run the example below and then exit:
>> If you click on "All music" and then exit, then everything's fine.
>> If you click on "Artist" and then exit, I get a Python or
>> wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
>> wxPython 2.2.5.
>
> It doesn't crash here (on Win2k.) Nothing in the code is jumping out at me
> as being wrong either.

    Any chance of a Win98 user on this list reproducing my problem.
    I've got crashes with this code on two different Win98 boxes
    with BeOpen Python 2.0 and wxPython 2.2.2 and 2.2.5. It's not
    a complete show-stopper for me, but it's irritating enough
    that I'd like to know what the problem is.

    Y.

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Shop online without a credit card
http://www.rocketcash.com
RocketCash, a NetZero subsidiary

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

>> So the problem comes when you run the example below and then exit:
>> If you click on "All music" and then exit, then everything's fine.
>> If you click on "Artist" and then exit, I get a Python or
>> wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
>> wxPython 2.2.5.
>
> It doesn't crash here (on Win2k.) Nothing in the code is jumping out at

me

> as being wrong either.

    Any chance of a Win98 user on this list reproducing my problem.
    I've got crashes with this code on two different Win98 boxes
    with BeOpen Python 2.0 and wxPython 2.2.2 and 2.2.5. It's not
    a complete show-stopper for me, but it's irritating enough
    that I'd like to know what the problem is.

The slightly modified version below shows what the problem is. The output
on win2k is this:

    [C:\temp\others] crash2.py
    OnSelChanged -- begin
    OnSelChanged -- end
    OnSelChanged -- begin
    OnSelChanged -- end
    OnCloseWindow - begin
    OnCloseWindow - end

and on win98 it is this:

    c:\stuff>python crash2.py
    OnSelChanged -- begin
    OnSelChanged -- end
    OnSelChanged -- begin
    OnSelChanged -- end
    OnCloseWindow - begin
    OnCloseWindow - end
    OnSelChanged -- begin
    OnSelChanged -- end

So you see there is a selection changed event AFTER the program has started
shutting down, probably as the selected tree item is being deleted. My
guess is that when your event handler executes this last time the list
window has already been destroyed and so is accessing memory that no longer
belongs to the process.

The fix is to either put a guard in the event handler (set a flag in
OnCloseWindow and check it there,) or perhaps to select the tree root item
in OnCloseWindow or wherever makes sense to do it.

BTW, I've found putting print statements in strategic places like this
really helpful in understanding how things work, what order events are
coming in, etc.

# ------------- BEGIN SAMPLE CODE ----------------------
from wxPython.wx import *

class MP3List(wxListCtrl):
    def __init__( self, parent ):
        wxListCtrl.__init__( self, parent, wxNewId() )

    def Set_contents( self, song_list ):
        self.ClearAll()
        for row_num in range( len(song_list) ):
            self.InsertStringItem( row_num, song_list[row_num] )

class RepositoryTree(wxTreeCtrl):
    def __init__(self, parent, list_win ):
        wxTreeCtrl.__init__( self, parent, wxNewId() )
        self.list_window = list_win
        EVT_TREE_SEL_CHANGED( self, self.GetId(), self.On_selection_change )

    def Set_contents( self ):
        self.root = self.AddRoot( "All music" )
        self.artist_index = self.AppendItem( self.root, "Artist" )
        self.Expand( self.root )

    def On_selection_change( self, event ):
        print "OnSelChanged -- begin"
        #self.list_window.Set_contents( ["Song"] )
        print "OnSelChanged -- end"

class Repository(wxSplitterWindow):
    def __init__(self, parent):
        wxSplitterWindow.__init__( self, parent, -1 )

        self.list_window = MP3List( self )
        self.tree_window = RepositoryTree( self, self.list_window )
        self.tree_window.Set_contents()

        self.SplitVertically( self.tree_window, self.list_window )
        self.SetMinimumPaneSize( 100 )
        self.SetSashPosition( 150 )

class ParoFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__( self, parent, id, title )
        self.repository_win = Repository( self )
        EVT_CLOSE(self, self.OnCloseWindow)

    def OnCloseWindow( self, event ):
        print "OnCloseWindow - begin"
        self.Destroy()
        print "OnCloseWindow - end"

class ParoApp(wxApp):
    def OnInit( self ):
        self.frame = ParoFrame( NULL, -1, "MyParo" )
        self.frame.Show( TRUE )
        self.SetTopWindow( self.frame )
        return TRUE

paro_instance = ParoApp(0)
paro_instance.MainLoop()

# ------------- END SAMPLE CODE ----------------------

···

On Monday, February 19, 2001 at 12:03:59 AM, Robin Dunn wrote:

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

>> So the problem comes when you run the example below and then exit:
>> If you click on "All music" and then exit, then everything's fine.
>> If you click on "Artist" and then exit, I get a Python or
>> wxPython crash on Windows. This is with Win98, BeOpen Python 2.0,
>> wxPython 2.2.5.

The slightly modified version below shows what the problem is.

So you see there is a selection changed event AFTER the program has started
shutting down, probably as the selected tree item is being deleted. My
guess is that when your event handler executes this last time the list
window has already been destroyed and so is accessing memory that no longer
belongs to the process.

The fix is to either put a guard in the event handler (set a flag in
OnCloseWindow and check it there,) or perhaps to select the tree root item
in OnCloseWindow or wherever makes sense to do it.

  Thanks a lot! I'll try it out.

  BTW, why exactly is the selection-changed event generated after
  the close-window event? Seems weird for what seems to be a wxWindows
  bug to manifest itself only on Win98 and Python 2.0. Also, it's
  strange for it not to happen when the tree event is selected ...

  Y.

···

On Monday, February 19, 2001 at 8:12:39 PM, Robin Dunn wrote:

On Monday, February 19, 2001 at 12:03:59 AM, Robin Dunn wrote:
  
# ------------- BEGIN SAMPLE CODE ----------------------
from wxPython.wx import *

class MP3List(wxListCtrl):
    def __init__( self, parent ):
        wxListCtrl.__init__( self, parent, wxNewId() )

    def Set_contents( self, song_list ):
        self.ClearAll()
        for row_num in range( len(song_list) ):
            self.InsertStringItem( row_num, song_list[row_num] )

class RepositoryTree(wxTreeCtrl):
    def __init__(self, parent, list_win ):
        wxTreeCtrl.__init__( self, parent, wxNewId() )
        self.list_window = list_win
        EVT_TREE_SEL_CHANGED( self, self.GetId(), self.On_selection_change )

    def Set_contents( self ):
        self.root = self.AddRoot( "All music" )
        self.artist_index = self.AppendItem( self.root, "Artist" )
        self.Expand( self.root )

    def On_selection_change( self, event ):
        print "OnSelChanged -- begin"
        #self.list_window.Set_contents( ["Song"] )
        print "OnSelChanged -- end"

class Repository(wxSplitterWindow):
    def __init__(self, parent):
        wxSplitterWindow.__init__( self, parent, -1 )

        self.list_window = MP3List( self )
        self.tree_window = RepositoryTree( self, self.list_window )
        self.tree_window.Set_contents()

        self.SplitVertically( self.tree_window, self.list_window )
        self.SetMinimumPaneSize( 100 )
        self.SetSashPosition( 150 )

class ParoFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__( self, parent, id, title )
        self.repository_win = Repository( self )
        EVT_CLOSE(self, self.OnCloseWindow)

    def OnCloseWindow( self, event ):
        print "OnCloseWindow - begin"
        self.Destroy()
        print "OnCloseWindow - end"

class ParoApp(wxApp):
    def OnInit( self ):
        self.frame = ParoFrame( NULL, -1, "MyParo" )
        self.frame.Show( TRUE )
        self.SetTopWindow( self.frame )
        return TRUE

paro_instance = ParoApp(0)
paro_instance.MainLoop()
# ------------- END SAMPLE CODE ----------------------

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

  BTW, why exactly is the selection-changed event generated after
  the close-window event?

Because end users are Microsoft's QA department.

Seems weird for what seems to be a wxWindows
  bug to manifest itself only on Win98 and Python 2.0.

There are different versions of the common controls on different windows
platforms, each with their own set of bugs. I would guess that you will see
the event happening after the close even on Python 1.5 but since it cleans
up objects in a different order, the list window may still exist at the
time.

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users