Board index » delphi » Delphi 1: Causes of GPF's??

Delphi 1: Causes of GPF's??

My program - which is not that complex (no databases and very few
components) runs fine up to the point where I try and close it & then I
get a GPF --- any ideas why?

Thanks
Derek.

--
                                                      dho...@csir.co.za
                                               No opinions. Just facts.
                                  http://www.geocities.com/Area51/6481/
                        "One warp core breach can really ruin your day."

 

Re:Delphi 1: Causes of GPF's??


Quote
Derek wrote:

> My program - which is not that complex (no databases and very few
> components) runs fine up to the point where I try and close it & then I
> get a GPF --- any ideas why?

> Thanks
> Derek.

Not without source...

--
Svante Granqvist                 Speech, Music and Hearing
Phone +46-8-790 7561             Box 700 14
Fax   +46-8-790 7854             S-100 44 Stockholm
mailto:sva...@speech.kth.se      http://www.speech.kth.se/~svante

Re:Delphi 1: Causes of GPF's??


Quote
Derek wrote:

> My program - which is not that complex (no databases and very few
> components) runs fine up to the point where I try and close it & then I
> get a GPF --- any ideas why?

        Probably you're freeing some component twice. Or something like
that. (Do you create any components in code, ie other than by dropping
them one the form in the IDE? Example: If you say

AComponent:= SomeComponentType.Create(Self);

in the form's OnCreate and then you say

AComponent.Free;

in the form's OnDestroy then that component's getting freed
twice.)

--
David Ullrich

?his ?s ?avid ?llrich's ?ig ?ile
(Someone undeleted it for me...)

Re:Delphi 1: Causes of GPF's??


Quote
Derek wrote:

> My program - which is not that complex (no databases and very few
> components) runs fine up to the point where I try and close it
> & then I get a GPF --- any ideas why?

We had this problem several months ago with our garden simulator
(written in Delphi & downloadable at http://www.gardenwithinsight.com )
The problem turned out to be a VCL error.  We independently discovered a
fix, but it is also in the VCL patches you get when you register
memmond.  It is also fixed in delphi 2.0.  You could also be getting the
problem for other reasons - like freeing a component twice.

Here are some more details I wrote up several months ago (but haven't
previously posted...):

The Delphi 1.0 application sometimes crashed when exiting.
It always crashed on the same line in MENUS.PAS:

function TMenuItem.GetCount: Integer;
begin
  if FItems = nil then Result := 0
  else Result := FItems.Count;  {<<<<< crashes when tries to get count}
end;

The problem comes about because:
after freeing the FItems field (a TMenuItem with a list of TMenuItems)
TMenu.destroy calls inherited
TComponent.destroy which calls
TComponent.RemoveComponent (for the form) which calls
TForm.Notification which calls
TForm.SetMenu(nil) (Menu property) which calls
TMenu.SetWindowHandle(0) (WindowHandle property) which calls
TMenu.UpdateImage which calls
TMenuItem.GetHandle (Handle property) which makes a new menu
(CreateMenu) and then calls
TMenuItem.PopulateMenu which calls
IterateMenus which on the Menu2.Count line calls
TMenuItem.GetCount which causes the crash because FItems was previously
freed.

The place where things go wrong is in TMenu.UpdateImage when
TMenuItem.GetHandle is called, since that object has already been freed.

After realizing this, I looked at the Delphi 2.0 VCL source, and sure
enough, Borland has changed something:

in function TMenu.UpdateImage: Boolean;

from:  BuildImage(Handle);
to:    if FWindowHandle <> 0 then BuildImage(Handle);

The new code avoids the call to GetHandle (through the Handle property)
in this case because
TMenu.SetWindowHandle(0) sets FWindowHandle to 0 before calling
TMenu.UpdateImage.

You could argue that things actually go wrong a bit earlier, in the call
from TForm.SetMenu(nil) to TMenu.SetWindowHandle(0), which violates the
notion that an object in the middle of being destroyed really shouldn't
have other objects doing things with it.  Certainly though, calling a
function of a freed object is an error.

After realizing this, I looked in more detail at the patches that come
with MemMonD.  It turns out there is a patch there that will also fix
this problem.  That patch is  different in implementation and doesn't
mention the crashing behavior - just  an associated leak.

We modified the VCL.  You might also just override TForm.Notification
in every form that uses a form menu.  Of course, maybe that might leave
popup menus still broken...

It took me over forty hours over two months to isolate this problem.  Of
those, it only took the last four to actually trace through the problem
once I decided it was probably a VCL bug.  The others were spent under
the assumption that the problem was a bug in my code - I thought I was
perhaps freeing something twice. I did find another bug involving
freeing custom components (which are freed by their owner and should not
be freed explicitly) in this process, plus a few memory leaks.

In an effort to find this bug, I ran the code under BoundsChecker for
Win 3.1,  purchased $300 Bounds Checker for Delphi 2.0, bought MemMonD
and Memory Sleuth (about $50 each), all of which I hoped would find a
bug  involving freeing something twice.  I almost bought a faster
computer just so I could realistically use BoundsChecker for Delphi 2.0
(which takes 20 minutes to start my application on a 486 DX 66 - 20 MB).
In the end, it took TDW to trace it through. I probably would have found
the bug faster, except I find TDW so awkward to use, and kind of resent
that I have to leave the integrated development environment to use it.

I guess these memory tools will be useful in the future,  and MemMonD
was another source of confirmation that there was a problem here in the
VCL.

I am a little annoyed at Borland, though.  Not because there was a bug -
that can happen to anyone.  I am annoyed because I called the Borland
tech support  $2 a minute advisor phone line several times (at a cost of
probably $100 or more),  and even asked them specifically to search
their bug database,  and they couldn't help me with this bug.  Since
Borland fixed this bug in 2.0, they must have known about it sometime.
Why couldn't Borland tech support tell me about a patch for this?  I
even resorted to calling their C++ advisor line to try to get tips on
using TDW since I thought maybe the staff there would be more familiar
with it.

I don't mind paying $2 a minute (now $3) for good tech support.  I guess
I could try to take Borland up on their money back offer for tech
support, but I am not sure exactly which calls I made were devoted to
this bug, or how much of them. The $100 is a rough guess.  What really
hurts is the week of my time I won't get back.

I still think Delphi is a good product. Also, Borland Tech support was
very helpful when I was starting out with Delphi.  I doubt the blame for
the situation of handling Delphi 1.0 bug fixes rests with them.  If
Borland's tech support is like most computer industry technical support
divisions, the people there are overworked, underpaid, highly stressed,
and not given good enough tools, time, or training to do their jobs. But
of course, we expect better than that from Borland, don't we?

-Paul Fernhout
Kurtz-Fernhout Software
kfs...@netins.net
========================================
Download a public beta release of our garden simulator
written using Delphi 1.0 at:
http://www.gardenwithinsight.com

Other Threads