madExcept error with FreeAndNil

delphi package - automated exception handling
Post Reply
ephillipe
Posts: 3
Joined: Thu Feb 12, 2009 8:54 pm

madExcept error with FreeAndNil

Post by ephillipe »

Hi, this error ocour when I call FreeAndNil of my Object. Withou madExcept don't raise nothing...

Code: Select all

date/time         : 2009-02-12, 17:52:15, 542ms
computer name     : VMERICK
user name         : erick <admin>
registered owner  : Desenvolvimento / Alterdata
operating system  : Windows XP Service Pack 2 build 2600
system language   : Portuguese
system up time    : 9 hours 39 minutes
program up time   : 39 seconds
processor         : Intel(R) Pentium(R) 4 CPU 3.20GHz
physical memory   : 49/255 MB (free/total)
free disk space   : (C:) 14,31 GB
display mode      : 1280x1024, 32 bit
process id        : $174
allocated memory  : 10,32 MB
executable        : ModRunner.exe
current module    : madExcept_.bpl
exec. date/time   : 2009-02-12 17:51
compiled with     : Delphi 7
madExcept version : 3.0h
contact name      : Erick
callstack crc     : $f68c0ab9, $bc40a7a8, $bc40a7a8
exception number  : 1
exception class   : EAccessViolation
exception message : Access violation at address 40008EEC in module 'rtl70.bpl'. Read of address 00000310.

main thread ($310):
40008eec +010 rtl70.bpl     System             @IntfClear
0040461b +11b ModRunner.exe uPrincipal 119 +22 TFormPrincipalRunner.ExecutarAgendamento
004043b1 +115 ModRunner.exe uPrincipal  78 +16 TFormPrincipalRunner.tmrAgendamentoTimer
0045ebf3 +00f vcl70.bpl     Extctrls           TTimer.Timer
0045ead7 +02b vcl70.bpl     Extctrls           TTimer.WndProc
77d2bcc7 +00a user32.dll                       DispatchMessageA
004e568b +083 vcl70.bpl     Forms              TApplication.ProcessMessage
004e56c2 +00a vcl70.bpl     Forms              TApplication.HandleMessage
004e58f2 +096 vcl70.bpl     Forms              TApplication.Run
0040541f +073 ModRunner.exe ModRunner   30  +9 initialization

disassembling:
[...]
0040460e        pop     ecx
0040460f        pop     ecx
00404610        mov     fs:[eax], edx
00404613        push    $404628
00404618        lea     eax, [ebp-$c]
0040461b      > call    -$3550 ($4010d0)       ; System.@IntfClear (rtl70.bpl)
00404620        ret
00404621        jmp     loc_401058
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Sometimes madExcept shows bugs which are there, but hidden without madExcept. Don't know if that is the case for you. Of course it could also be a bug in madExcept.

How does your code in unit "uPrincipal" around line 119 look like? If the function is not too long, maybe you could post the full function code here?
ephillipe
Posts: 3
Joined: Thu Feb 12, 2009 8:54 pm

Post by ephillipe »

madshi wrote:Sometimes madExcept shows bugs which are there, but hidden without madExcept. Don't know if that is the case for you. Of course it could also be a bug in madExcept.

How does your code in unit "uPrincipal" around line 119 look like? If the function is not too long, maybe you could post the full function code here?
My function is realy simple.
She load a BPL in runtime, create a registred class and then Execute the function associated.

Code: Select all

procedure TFormPrincipalRunner.ExecutarAgendamento(Agendamento: TAgendamento);
var
  vObj: TObject;
  AForm: TCustomForm;
  AClass: TPersistentClass;
begin
  if not Assigned(Agendamento) then
    Exit;
  LoadPackage(Agendamento.ModuloExecucao);
  AClass := GetClass(Agendamento.ClasseExecucao);
  if AClass <> nil then
  begin
    try
      AForm := TComponentClass(AClass).Create(nil) as TCustomForm;
      try
        if AForm.GetInterface(IRunnerModuleBase, vObj) then
        begin
          dmPrincipal.MomentoExecucao := meExecutandoModulo;
          (AForm as IRunnerModuleBase).Executar;
        end;
      finally
        FreeAndNil(AForm);
        AddLogModulos('ExecutarAgendamento finaliza corretamente...');
      end;
    except
      on Erro: Exception do
      begin
        AddLogModulos(Erro.Message);
      end;
    end;
  end;
end;
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

I think your code is buggy. Calling "AForm.GetInterface(IRunnerModuleBase, vObj)" probably increases the reference count of AForm from 0 to 1. Then when "vObj" goes out of scope, Delphi automatically decreases reference count from 1 to 0 again and as a result the automatic interface cleanup solution frees the form. But you have already freed it yourself! I think if "AForm.GetInterface" succeeds you must not free AForm manually, anymore, to avoid having the form freed twice. You can check it out yourself: Remove that "FreeAndNil(AForm)". And then set a breakpoint in "AForm.Destroy" and check whether it's called. I think it will be called by the interface logic.
ephillipe
Posts: 3
Joined: Thu Feb 12, 2009 8:54 pm

Post by ephillipe »

madshi wrote:I think your code is buggy. Calling "AForm.GetInterface(IRunnerModuleBase, vObj)" probably increases the reference count of AForm from 0 to 1. Then when "vObj" goes out of scope, Delphi automatically decreases reference count from 1 to 0 again and as a result the automatic interface cleanup solution frees the form. But you have already freed it yourself! I think if "AForm.GetInterface" succeeds you must not free AForm manually, anymore, to avoid having the form freed twice. You can check it out yourself: Remove that "FreeAndNil(AForm)". And then set a breakpoint in "AForm.Destroy" and check whether it's called. I think it will be called by the interface logic.
Hi,
I comment FreeAndNil code and my class Destroy don't called.
I discover an error in EXECUTAR method. But, is strange madException don't show the real class/function raise exception.
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Well, I'm not sure exactly, but you have a try..except block in ExecutarAgendamento which eats all exceptions. Maybe that's the reason why?
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

vObj is an IInterface, not a TObject. However, you should not mix classes and interfaces.
Post Reply