[lazarus] New Bug Entered

Mattias Gaertner nc-gaertnma at netcologne.de
Mon Jul 14 09:21:21 EDT 2003


On Mon, 14 Jul 2003 14:38:50 +0200 (W. Europe Daylight Time)
Michael Van Canneyt <michael.vancanneyt at wisa.be> wrote:

> 
> 
> On Mon, 14 Jul 2003, Mattias Gaertner wrote:
> 
> > On Sun, 13 Jul 2003 18:28:08 -0400
> > bugtracker at miraclec.com wrote:
> >
> > >
> > > Title: Datamodule generates AV on Lazarus exit
> > >
> > > Entered by: Tom Lisjac
> > >
> > > When a datamodule is renamed, OldCreateOrder is set and OnCreate and
> > > OnDestroy events exist, Lazarus will AV upon exit with 1.0.10. Here
> > > are the steps to reproduce:
> > >
> > > Bring up Lazarus in a new project.
> > > Add a datamodule with File | New | Datamodule
> > > With Property editor:
> > >    Rename the datamodule to dmt
> > >    Set OldCreationOrder to True
> > >    Create empty OnCreate and OnDestroy event handlers
> > > Exiting Lazarus (saving or not) generates an AV
> > >
> > > This problem appeared after upgrading to 1.0.10 in a datamodule that
> > > had been working fine with 1.0.7.
> >
> > Now, there you found a difficult thing. I always wonder, when it will
> > appear. The IDE creates datamodule/forms descendents on the fly. That
> > means, it really creates new classes and procedures at runtime. These
> > procedures are empty and do nothing. The current trick is to copy an
> > empty procedure. I was always sure, that this will give us trouble, as
> > soon as the caller checks the stack or uses some special calling
> > convention. Now you find an example:
> >
> > try
> >   AnEvent(Self);
> > except
> > end;
> >
> > When the 'except' frees the exception frame, it runs into trouble
> > (internal error).
> > I have commented the try..except in the LCL, so this error is hidden.
> > One correct solution is to create better "empty procedures". This means
> > an empty procedure, with the right length of parameters. I'm not sure
> > how to do this for all kinds of calling conventions and processors.
> 
> You can't.

Why that?


> > Another solution is to simulate procedures. That means the procedures
> > are not really set. But this requires changing TReader/TWriter to handle
> > fake events and the RTTI will be incomplete.
> > I prefer the first solution.
> >
> > Maybe a fpc guru can give me a hint.
> 
> Before destroying your instances, all methods should simply be set to nil.
> This is OK as long as it happens after the form file was written.

Why do you think, the problem is only the destructor?
Maybe this helps:
When the IDE creates an event (reading a form or user creates a new event)
it needs a TMethod record. That means the Self pointer "Data" and the
procedure address "Code". Because the FCL and the RTTI uses the Code to
identify a procedure, every event needs a unique procedure. The IDE uses a
dirty trick and allocates a few bytes and copies the code from an empty
method.
Because the empty method has no parameters, it is, strictly speaking, only
compatible to events without parameters. In fact it is something like this:

  MyDataModule.AnNotifyEvent:=TNotifyEvent(@MyDataModule.SimpleProc);

A simple 

AnNotifyEvent(Self) 

works (at least on i386). But a

try
  AnNotifyEvent(Self);
except
end;

does not work.


Mattias






More information about the Lazarus mailing list