【问题标题】:Can Ada be told not to catch EXCEPTION_ACCESS_VIOLATION可以告诉 Ada 不要抓住 EXCEPTION_ACCESS_VIOLATION
【发布时间】:2018-09-13 21:35:34
【问题描述】:

我们有一个在 Windows 上运行的大型 Ada/C++ 系统(使用 Gnatpro 7.3.2),它很少会因 0xC0000005 Windows 内存冲突而严重崩溃。我试图通过创建一个调用 C++ 库的小型 Ada 程序来简化,并且该库尝试写入地址 0x07。但在这种情况下,Ada 子系统并没有得到预期的 C0000005,而是报告了一个 PROGRAM ERROR 消息 EXCEPTION_ACCESS_VIOLATION 和一个不错的堆栈跟踪。

为了找到这个罕见的错误,我首先编写了一个写入地址 7 的 C++ 程序,这导致了预期的 C000005,但这使用了 MSVC 运行时。我的小 Ada 程序表现出不同的行为。是否可以禁用捕获内存违规的 Ada 运行时层?

【问题讨论】:

  • 您可能必须修改运行时才能做到这一点。如果您与 AdaCore 签订了支持合同,您可以询问他们是否可以帮助您。
  • 我猜你在某个地方有一些内存损坏。如果堆栈损坏,则在引发异常时可能会发生非常糟糕的事情,因为它可能会在展开堆栈时失败并产生其他错误。检查 Ada 代码释放并仍在使用的 C++ 对象。
  • 您使用的是 GNAT Pro,您没有支持合同吗?

标签: c++ windows ada gnat


【解决方案1】:

您实际上在这里问了几个不同的问题:

  1. 问:(Windows) 0xc0000005 访问冲突和 Ada PROGRAM ERROR/EXCEPTION_ACCESS_VIOLATION 有什么区别?

  2. 问:我可以在我的 Ada 应用程序中做些什么?

为了更好地理解 0xc0000005,请看这里:

What exactly is the scope of Access Violation '0xc0000005'?

要处理Ada程序错误,为什么不直接使用标准的Ada“异常”块,例如:

with Ada.Exceptions;  use Ada.Exceptions;
...
exception
  when Error: EXCEPTION_ACCESS_VIOLATION =>
    Put ("Access Violation: ");
    Put_Line (Exception_Name (Error));
    Put (Exception_Message (Error));
  when Error: others =>
    Put ("Something Else: ");
    Put_Line (Exception_Information(Error));
end;

【讨论】:

  • (1) EXCEPTION_ACCESS_VIOLATION 不是 Ada 例外,(2) OP 的问题是他们获得了 E.A.V. 而不是 Program_Error Ada 例外)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多