Delphi 2007 - 程序化操作"忽略的例外"名单

时间:2014-03-23 22:40:58

标签: delphi exception delphi-2007 integer-overflow

我有一个应用程序,在调用FormatDateTime时偶尔会返回整数溢出。虽然我发现了问题herehere,但我不知道是什么情况触发了这个问题。

我目前的解决方法是包装函数并处理异常:

function FormatDateTimeEx (const FormatString : ANSIString ;
                                 DateTime     : TDateTime) : ANSIString ;
begin
try
    Result := FormatDateTime (FormatString, DateTime) ;
except
    Result := '???' ; 
    end ;
end ;

解决了导致编译后的可执行文件崩溃的问题,但是如果调试器在IDE中运行程序时没有在EIntOverflow异常中中断,我也会更喜欢它。我不想通过告诉IDE忽略EIntOverflow异常来做到这一点,因为当发生未捕获的整数溢出时,它不会在其他情况下中断(对吗?)。

是否有一种编程方式(编译时或运行时)告诉IDE本地忽略异常类,对于那些可能发生异常的情况,你已经知道并正在处理它?<​​/ p >

3 个答案:

答案 0 :(得分:3)

  

是否有一种编程方式(编译时或运行时)告诉IDE本地忽略异常类,对于那些可能发生异常的情况,你已经知道并正在处理它?<​​/ p >

没有。

您无法要求调试器忽略某些EIntOverflow例外但不会忽略其他例外情况。你可以忽略它们,也可以不忽略它们。您可以通过异常类控制调试器中哪些异常中断的唯一方法。您不能要求调试器忽略程序的某个部分中的异常,而忽略另一部分中的异常。

坦率地说,在我看来,解决这个问题的正确方法是弄清楚为什么你首先会触发这些例外。并采取措施防止它们发生。例外是您需要解决的代码中的错误的症状。

答案 1 :(得分:3)

您无法控制调试器异常处理,但您可以控制导致其中一些异常的编译器选项。 以下是如何在本地禁用编译器切换然后返回到先前状态:

1)初始化 - 在单元的开头某处或者可能在单独的* .inc文件中。

{$IFOPT R+}
  {$DEFINE RangeCheckOn}
{$ENDIF}

这里保存编译器开关的初始状态(即在项目设置中设置)状态。 2)现在,用法:

{$R-}
  ...your code here with disabled switch...
{$IFDEF RangeCheckOn}
  {$R+}
{$ENDIF}

这里禁用开关,在没有它的情况下执行一些代码,并在完成后将其恢复到初始状态。

我正在使用这个技巧在(U)Int64上进行一些位移操作,这会在触摸MSB时产生错误的EIntOverflow异常(编译器错误是XE2的实际错误,对于新版本不确定)。

但我同意以前的答案,你应该检查引发异常的真正原因。我建议你使用FormatEx版本,如果出现异常,将记录参数值。因此,您可以跟踪导致异常的值,并检查它是否是可重现的案例。

答案 2 :(得分:1)

  

是否有一种编程方式(编译时或运行时)告诉IDE本地忽略异常类,对于那些可能发生异常的情况,你已经知道并正在处理它?<​​/ p >

不在代码中,没有。但是,可以使用断点在调试器中完成。

用两个断点包装受影响的代码:

function FormatDateTimeEx(const FormatString: AnsiString; DateTime: TDateTime): AnsiString;
begin // <-- breakpoint
  try
    Result := FormatDateTime (FormatString, DateTime) ;
  except
    Result := '???'; 
  end;
end; // <-- breakpoint

进入第一个断点的属性并启用忽略后续例外选项并禁用中断选项。

进入第二个断点的属性并启用处理后续例外选项并禁用中断选项。