如何识别和捕获TDataModule Destroy发生的Delphi EAccessViolation?

问题描述 投票:0回答:1

我已将 Delphi 2009 桌面应用程序转换为控制台应用程序(添加

{$APPTYPE CONSOLE}
并避免创建 MainForm,而是创建 TDataModule 后代并使用它们),现在我收到 MadExcept 调用堆栈:

exception class    : EAccessViolation
exception message  : Access violation at address 0085840B in module 'HRSuite.exe'. Read of address 0C0B7260.

main thread ($4cc0):
0085840b +03f HRSuite.exe  DBClient            1212  +3 TCustomClientDataSet.CloseCursor
00567fef +0a7 HRSuite.exe  DB                 10601 +21 TDataSet.SetActive
00567df0 +004 HRSuite.exe  DB                 10553  +0 TDataSet.Close
00559c2e +012 HRSuite.exe  DB                  4066  +3 TField.Destroy
0049ed23 +047 HRSuite.exe  Classes            11584  +9 TComponent.DestroyComponents
0049eb17 +04f HRSuite.exe  Classes            11486  +8 TComponent.Destroy
0049fd42 +066 HRSuite.exe  Classes            12519  +6 TDataModule.Destroy
005c9384 +0b8 HRSuite.exe  HRBaseDMU            349 +22 THRBaseDM.Destroy
0049ed23 +047 HRSuite.exe  Classes            11584  +9 TComponent.DestroyComponents
005353e9 +035 HRSuite.exe  Forms               1755  +9 DoneApplication
0054325a +022 HRSuite.exe  Forms              11116  +1 Finalization
00405ac9 +039 HRSuite.exe  System             12865 +20 FinalizeUnits
00468428 +054 HRSuite.exe  madExcept                    InterceptFinalizeUnits
00468430 +000 HRSuite.exe  madExcept                    InterceptHalt0FinalizeUnits
00405ec5 +09d HRSuite.exe  System             13632 +61 @Halt0
010cabb9 +151 HRSuite.exe  HRSuite              545 +37 initialization
75a0fcc7 +017 KERNEL32.DLL                              BaseThreadInitThunk

据我所知,我至少尝试确定哪个 DataModule 在 Destroy 中存在异常:

procedure THRBaseDM.DataModuleDestroy(Sender: TObject);
var tmp: Integer;
begin
  Writeln(Self.Name);
  Writeln('BASE before destroy: '+Self.Name);
  inherited;
  Writeln('BASE after destroy: '+Self.Name);
end;

但最终输出行是:

FreeDaysDM
BASE before destroy: FreeDaysDM
BASE after destroy: FreeDaysDM
An error occurred in the application.

我预计在没有关闭通知的情况下会有“销毁前的基础:...”,这可能是识别有问题的 DataModule 的方法,但是在没有关闭通知的情况下没有打开通知,所以 - 我应该尝试获取有关的信息以某种不同的方式冒犯 DataModule。但如何呢?

delphi access-violation madexcept
1个回答
0
投票

OnDestroy
不是捕获异常的地方,相反,必须在数据模块中重写析构函数本身:

public
    destructor Destroy; override;

然后

destructor THRBaseDM.Destroy;
var i: Integer;
begin
  Writeln('REAL BASE before destroy: '+Self.Name);
  try
    //... some large business or technical code
    inherited;
  except
    on E: Exception do begin
      Writeln('REAL '+Self.name);
      Writeln('REAL '+E.Message);
    end;
  end;
  Writeln('REAL BASE after destroy: '+Self.Name);
end;

这样的覆盖给我们带来了预期的错误报告。

© www.soinside.com 2019 - 2024. All rights reserved.