Recent

Author Topic: TObject.Free can cause SIGSEGV  (Read 7737 times)

dfeher

  • New Member
  • *
  • Posts: 19
TObject.Free can cause SIGSEGV
« on: April 14, 2010, 07:12:56 pm »
Hello!

Some misplaced inherited Free; command in a class' destructor caused several hours of bug tracking for me. I had SIGSEGV when freeing some classes without an ancestor (so ancestor was TObject). I think the TObject.Free procedure should have been run when calling inherited Free, without any errors but then I saw the code below. It's from objpas.inc:

Code: [Select]
      procedure TObject.Free;

        begin
           // the call via self avoids a warning
           if self<>nil then
             self.destroy;
        end;

I've noticed the self<>nil. I think it should be better to use assigned(self) instead.

Am I right and this have to be reported as a bug or am I wrong?

eny

  • Hero Member
  • *****
  • Posts: 1646
Re: TObject.Free can cause SIGSEGV
« Reply #1 on: April 14, 2010, 07:31:06 pm »
Why would you want to override TObject.Free?
Can't you do the housecleaning in your classes' destructor?

Free is particularly useful if you reuse object variables that might have been freed before.
For that reason you can use the procedure FreeAndNil.
All posts based on: Win10 (Win64); Lazarus 3_4  (x64) 25-05-2024 (unless specified otherwise...)

dfeher

  • New Member
  • *
  • Posts: 19
Re: TObject.Free can cause SIGSEGV
« Reply #2 on: April 14, 2010, 07:38:37 pm »
My class' destructor implementation looks like this:

Code: [Select]
destructor TMyClass.Free;
begin

  { ...Some housecleaning... }

  inherited Free;
end;

So I didn't want to override TObject.Free just placed inherited Free in my destructor and I think it normally mustn't cause any errors.

eny

  • Hero Member
  • *****
  • Posts: 1646
Re: TObject.Free can cause SIGSEGV
« Reply #3 on: April 14, 2010, 08:01:53 pm »
Hm, that doesn't look like a good idea at all.
You're changing the default behaviour (as in 'expected') of the Free method.
And you're mixing two different freeing mechanisms.

What could happen is that when you call your own Free destructor, which is destroying the object, eventually calls the Free method, which in turn calls the Destroy destructor of the object you are already destroying.


All posts based on: Win10 (Win64); Lazarus 3_4  (x64) 25-05-2024 (unless specified otherwise...)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11181
  • Debugger - SynEdit - and more
    • wiki
Re: TObject.Free can cause SIGSEGV
« Reply #4 on: April 14, 2010, 09:29:28 pm »
My class' destructor implementation looks like this:

Code: [Select]
destructor TMyClass.Free;
begin

  { ...Some housecleaning... }

  inherited Free;
end;

So I didn't want to override TObject.Free just placed inherited Free in my destructor and I think it normally mustn't cause any errors.

So yes, this code must crash.

In TOBject Free is a procedure, not a destructor. But it does call a destructor.

In you code Free is a destructor, so when your Free has run, your onject gets destroyed. But it has been destroyed by Free in the meantime...

So at the end of your Free an already destroyed object is destroyed again.

If Free was a destructor, that would be ok => because calling an inherited destructor, within a destructor does not trigger a 2nd destruction.

Your code fails for the same reason as the following example (not tested)

Var // global
  Foo: TFoo;

Destructor TFoo.Destroy;
begin
  Foo.Destroy;
  inherited; // optional / makes no differnece
end;

Procedure SomeElse;
begin
  Foo.Destroy;
end;

Foo Destroy will be called twice.







dfeher

  • New Member
  • *
  • Posts: 19
Re: TObject.Free can cause SIGSEGV
« Reply #5 on: April 15, 2010, 08:41:11 am »
I think it's impossible to call the implemented function from itself but I understand the problem. To be short: my class would have been destructed twice this way. It's clear. But I think self<>nil is not safe for checking class instance existence.

Thanks for the answers!

 

TinyPortal © 2005-2018