4

我正在使用 Ada 语言开发一个大型项目(大约 10000 行纯代码)。在使用基于契约的编程过程中(Ada-2012 功能,如前置条件、后置条件、类型不变量等),我发现当断言或条件出错时,程序终止,因此断言已被检查,但没有有关类型和错误位置的任何消息。

然后,为了确定问题是否与 ada 2012 功能有关,或者与任何运行时错误有关,我尝试插入一个与断言/合同无关的简单运行时错误:除以零。

declare
    X : Integer := 1 - 1;
    Y : Integer := 1 / X;
begin
    null;
end;

在这种情况下,编译器建议我将引发异常,但在运行时程序完全终止,但任何内容都会打印出来。因此,问题出现在各种运行时检查失败中,不仅仅是那些与断言有关的问题。

此外,我尝试用几行代码创建一个新项目,以尝试简单的运行时错误(如除以零之前)以及先决条件和断言失败。在这个小项目中,程序会在控制台上打印所有错误。只有大型项目会受到问题的影响。

我的问题是问题可能出在哪里?为什么这只影响我的项目而不是简单的、刚刚创建的项目?是否有禁止打印运行时检查失败的选项?我在 XUbuntu 13.10 上运行。我正在使用 gnat、gps、gnatcoll、aws、polyorb 的最新 (2013) gpl 版本。我正在使用开关“-gnata”和“-gnat12”进行编译。

非常感谢您的帮助。

4

4 回答 4

3

在我看来,您的程序中的某些东西很可能破坏了 GNAT 的机制,该机制用于打印您通常会因未处理的异常而获得的消息。

这是在文件 a-elchha.adb 中的 Ada.Exceptions.Last_Chance_Handler 中完成的(在 GCC 4.8.1 中,据我所知在 GNAT GPL 2013 中)。在一些关闭的东西之后,打印是通过 stderr 完成的;您可以尝试用可以让您有更多机会进行调查的东西替换标准的最后机会处理程序。

或者,您可以使用调试器吗?我相信你可以告诉 GDBcatch exception unhandled哪个应该有帮助。

如果您想在运行时替换文件,请将替换与您的源代码一起使用,并使用-a标志告诉gnatmake重新编译它和任何依赖源。

于 2014-01-31T15:56:01.733 回答
3

如果你想使用 GNAT 作为一个合适的 Ada 编译器,你至少应该传递这些参数:

  • "-fstack-check", -- 生成堆栈检查代码(Ada 的一部分)
  • "-gnata", -- 启用断言(Ada 的一部分)
  • "-gnato", -- 溢出检查(Ada 的一部分)

我个人已经编写了这个项目文件,我用它来将我的首选参数设置为 GNAT:

--  O mighty Emacs, please use -*- Ada -*- mode in this lowly file.

abstract project Ada_2012 is
   for Source_Dirs use ();

   package Builder is
      for Default_Switches ("Ada")
        use ("-m");
   end Builder;

   package Compiler is
      for Default_Switches ("Ada")
        use ("-fstack-check", --  Generate stack checking code (part of Ada)
             "-gnata",        --  Enable assertions            (part of Ada)
             "-gnato13",      --  Overflow checking            (part of Ada)
             "-gnatf",                      --  Full, verbose error messages
             "-gnatwa",                     --  All optional warnings
             "-gnatVa",                     --  All validity checks
             "-gnaty3abcdefhiklmnoOprstux", --  Style checks
             "-gnatwe",                     --  Treat warnings as errors
             "-gnat2012",                   --  Use Ada 2012
             "-Wall",                       --  All GCC warnings
             "-O2");                        --  Optimise (level 2/3)
   end Compiler;
end Ada_2012;

我在我的所有 Ada (2012) 项目文件中“使用”这个文件,以便轻松访问我的标准设置。这是一个示例(来自http://repositories.jacob-sparre.dk/lego-tools):

--  O mighty Emacs, please use -*- Ada -*- mode in this lowly file.

with "ada_2012";

project LEGO_Tools is
   for Source_Dirs use ("src/",
                        "../../Mathematics_and_Statistics/**");

   for Main use ("build_mpd_file",
                 "fractal_landscape",
                 "outline_boundaries",
                 "pgm_to_ldraw",
                 "split_ldraw_file");

   package Builder  renames Ada_2012.Builder;
   package Compiler renames Ada_2012.Compiler;

   for Object_Dir use "obj/";
   for Exec_Dir   use "bin/";
end LEGO_Tools;
于 2014-01-29T07:24:12.303 回答
1

您是否有机会使用任务,并且异常发生在任务中(然后静默终止),程序随后因非异常原因而终止?

通常,由于异常而终止的任务会以静默方式执行(当您的任务中的其他异常处理程序帮助看到这一点时,您通常希望任务的顶部)。

于 2014-01-31T16:03:10.747 回答
0

有一些与获取回溯信息相关的开关。从文档中:

-E 当目标支持时,将回溯存储在异常发生中。另请参阅包 GNAT.Traceback 和 GNAT.Traceback.Symbolic 了解更多信息。请注意,在 x86 端口上,您不得使用 -fomit-frame-pointer gcc 选项。

我觉得这是必须的。

于 2014-01-28T22:05:40.223 回答