[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Random abend reported
From: |
Greg Chicares |
Subject: |
Re: [lmi] Random abend reported |
Date: |
Sat, 10 Dec 2005 02:56:54 +0000 |
User-agent: |
Mozilla Thunderbird 1.0.2 (Windows/20050317) |
On 2005-12-9 0:53 UTC, Greg Chicares wrote:
> Vadim--I'm trying to track down an abnormal termination
[...]
> It seems to occur when lmi is closed while it has an MDI child
> window open. This seems to have arisen about the time I did this:
>
> http://savannah.nongnu.org/cgi-bin/viewcvs/lmi/lmi/main_wx.cpp.diff?r1=1.26&r2=1.27
>
> and I wonder whether you could look at that change and tell me if
> I did something that looks wrong. I was trying to follow a more
> typical way of handling command-line arguments, so that we wouldn't
> need the __arg[cv] workaround that works only with the msvc rtl.
Because I can't seem to get a production build:
wx-2.5.4, MinGW gcc-3.4.2, lmi branch
to work with gdb, as described here:
http://lists.gnu.org/archive/html/lmi/2005-12/msg00018.html
I tried working with an experimental build:
wx-2.5.1, MinGW gcc-3.2.3, skeleton branch
which seems better behaved. Running with that branch's '--test' option, I got:
C:/opt/skeleton/bin[0]$/MinGW-20030915/bin/gdb skeleton.exe
GNU gdb 5.2.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-mingw32"...
(gdb) set arg --test
(gdb) r
Starting program: C:\opt\skeleton\bin/skeleton.exe --test
warning: 01:42:51: Debug: In file ../../src/msw/app.cpp at line 447:
'Unregister
Class(no redraw MDI parent frame)' failed with error 0x00000584 (class still
has
open windows.).
Program exited with code 037777777777.
(gdb)
Now, that message from wx:
"class still has open windows."
seems closely related to the defect report:
> It seems to occur when lmi is closed while it has an MDI child window open.
so I thought I'd try to prevent it.
This is all happening in Skeleton::OnInit(). The wx documentation says:
wxApp::OnInit
bool OnInit()
This must be provided by the application, and will usually create the
application's main window, optionally calling wxApp::SetTopWindow. You
may use OnExit to clean up anything initialized here, provided that the
function returns true.
With '--test', we return false. Skeleton::OnExit() does perform some
cleanup. But even if that cleanup doesn't happen, the worst consequence
I'd expect is a memory leak, not a crash.
Notice that if you want to to use the command line processing provided
by wxWidgets you have to call the base class version in the derived
class OnInit().
See below.
Return true to continue processing, false to exit the application
immediately.
With '--test', we return false: we want to exit the application immediately.
I wondered whether I should call wxApp::OnInit explicitly in the application
class's OnInit. I tried calling it thus:
bool Skeleton::OnInit()
{
wxApp::OnInit();
...
but that invoked the wx parser, and I'm using GNU getopt instead. I conclude
that I shouldn't do that. I want wx only to copy the command-line arguments
to wxApp::argc and wxApp::argv, not to parse them.
Here are some more experiments:
bool Skeleton::OnInit()
{
if(false == ProcessCommandLine(argc, argv))
{
return false;
}
...
Some options return here, but not '--test', which must use the frame window,
so it returns later.
frame_->Show(true);
SetTopWindow(frame_);
if(run_unit_tests_and_exit_immediately_)
{
mvc_test(frame_).Test();
...
// The wx documentation for OnExit() says "Note that it is not
// called at all if OnInit failed." Experimentally, try
// calling it explicitly, even though that seems weird.
// OnExit();
// That doesn't help: the same message is displayed.
That doesn't solve the "class still has open windows" problem.
But probably it's a good idea to do it anyway, to prevent the resources that
Skeleton::OnInit() deletes from leaking.
// wxApp::OnExit();
// Same outcome again.
Or perhaps it would be better to call the base class's OnExit(), but that
doesn't solve the "class still has open windows" problem either.
Looking through the wxApp member functions, I thought of trying this:
// This doesn't prevent that message either:
// ExitMainLoop();
which doesn't solve the problem at hand. However:
// But the wx documentation for ExitMainLoop() says "You
// should normally exit the main loop (and the application)
// by deleting the top window.
// delete GetTopWindow();
// That does seem to work, but explicitly to delete a window
// managed by wx seems strange. And the wx documentation says
// "When deleting a frame or dialog, use Destroy rather than
// delete", so instead try:
// GetTopWindow()->Destroy();
// That seems to work as well. However, the wx documentation
// elsewhere suggests using Close() instead: "The advantage of
// using Close instead of Destroy is that it will call any
// clean-up code defined by the EVT_CLOSE handler; for example
// it may close a document contained in a window after first
// asking the user whether the work should be saved.
GetTopWindow()->Close();
// That seems to work as well, and seems best of all according
// to the wx documentation.
return false;
}
Any of these solutions prevents the "class still has open windows" warning:
(gdb) r
Starting program: C:\opt\skeleton\bin/skeleton.exe --test
Program exited with code 037777777777.
(gdb)
Have I analyzed this correctly and chosen the best solution?