Possible obscure causes for Abstract Error in Delphi?
Asked Answered
P

5

8

In a Delphi 7 project we installed FastMM. Soon after that we noticed one of the forms started to issue Abstract Error message on close. I have debugged this extensively and I can't find the reason so far. The usual reason for this error message doesn't seem to apply here. The application doesn't define abstract classes. I also searched the form for a possible use of TStrings or something like that. Most importantly, we didn't (well, we think we didn't) make any changes to this form. It just broke.

  1. Are there some other possible causes for this error besides trying to call unimplemented method?
  2. Is there some possibilty that FastMM has enabled some obscure bug in the application, that remained hidden until now?

If the answer to these questions is no, then I'll just continue to search for an unimplemented method call, relieved that I am not missing something else.

Plop answered 12/8, 2012 at 18:5 Comment(2)
I have experienced "Abstract Error" when a form was created, usually it happens when you create a form(Form1), add components, etc. and then create another form(Form2) that inherits Form1, save everything, all good thus far, now, if you modify Form1(add component, modify component property...) save and rebuild, when form2 is created -> bam, abstract error, since then, I've always avoided form inheritance in design.Feign
These could be overload methods that you ended up putting one of them as reintroduce (It happened to me)Bercy
H
12

If there is memory corruption then all sort of errors can be raised and it is very difficult to find the cause.

To answer your questions: 1) Yes abstract error can also be caused by memory corruption, and 2) Yes enabling FastMM can make bugs visible that normally pass unnoticed (but should still be fixed).

Some general advice for finding memory errors:

  1. Try "FullDebugMode" setting in FastMM.
  2. Make sure everything you Create is matched with a Free.
  3. Make sure nothing is freed more than once.
  4. Make sure an object is not used after it has been freed (or before it has been created).
  5. Turn on hints and warnings (and fix them when they occur).
Hurlbut answered 12/8, 2012 at 18:20 Comment(7)
+1. I'd add 5. Turn on hints and warnings (and fix them when they occur)Miceli
@KenWhite: Absolutely. And I'd make that 1. Turn on hints and warnings..., emphasis on 1. :-)Macintosh
@KenWhite Added :-) Only problem is that in legacy code there could be hundreds of warnings and fixing them (incorrectly) risk introduce new bugs. So it must be done carefully.Hurlbut
Related to number 2. This will "only" cause a memory leaks, not access violations.Brita
To solve EscapeVelocity's problem I would concentrate on 4.Brita
In this particular case I would also replace all .Free with FreeAndNil().Brita
I would concentrate on #4. He MUST also fix ALL warnings! The compiler is serious about that. It wouldn't raise an warning without a valid reason. Fix that and you will probably fix your problem.Brita
L
3

"It just broke" - it was probably always broke but now you know.

I have seen problems when closing a form as part of a button event. The form gets destroyed and then the remainder of the button messages get dispatched to a no-longer existing button. The Release method avoids this by (from memory) posting a wm_close message back to the form

Lictor answered 13/8, 2012 at 3:27 Comment(1)
Your answer just helped me. I had a button that deleted itself and added new buttons. Trick was to set a semaphore to reload after button code exit.At
B
2

You could try to add u_dzAbstractHandler to your project. It should raise the abstract error where the method was called, so it is easier to debug it. Of course this only helps when the error occurs when running in the debugger.

https://osdn.net/projects/dzlib-tools/scm/svn/blobs/head/dzlib/trunk/src/u_dzAbstractHandler.pas

Bianchi answered 13/8, 2012 at 8:42 Comment(2)
How do install it? You just put the unit into the USES list of the project?Brita
Yes, as simple as that.Bianchi
B
2

Answer to question 1 "Are there some other possible causes for this error besides trying to call unimplemented method?"

Yes. This is what caused in my case an Abstract Error:

TWinControl(Sender).Visible:= FALSE;        

This worked when sender was a TButton but raised the error (of course) when the sender was something else (like TAction). It was obviously my fault. I should have used "as" instead of a hard typecast.

Answer to question 2: Yes. I have seen that happening too. We should be very clear that this doesn't mean that FastMM is buggy. The bug was 'dormant'. FastMM only triggered it.
Actually you should rely on FastMM even more to find your issue. Switch FastMM to full debug mode for this. It will help you with:

Make sure an object is not used after it has been freed (or before it has been created)

Also, in a few cases, the whole project was screwed up and I got the Abstract error. Nothing worked until I deleted the DPROJ file. Just do a compare between your current DPROJ file and the one in your back and you will see how the IDE f**** up the file.

You MUST also fix ALL warnings the compiler shows! The compiler is serious about that. It wouldn't raise an warning without a valid reason. Fix that and you will probably fix your problem.

In this particular case I would also replace all .Free with FreeAndNil().

Brita answered 29/8, 2014 at 9:59 Comment(0)
H
0

Could be that one of your abstract functions/procedures in the base class is not implemented;

try this :

e.g

 type

   TBaseClass = class (TObject)

 public

      procedure DoSomething;  virtual; abstract; //not implemented procedure

 end;


  type

    TInheritedClass = class (TBaseClass)

 public

      procedure DoSomething; override;

   end;

//Implementation

procedure TInheritedClass.DoSomething;

begin

 //your code

end;
Hispanic answered 9/10, 2018 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.