Ada程序不会打印任何运行时错误

时间:2014-01-28 12:08:14

标签: runtime-error ada code-contracts assertions gnat

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

然后,为了弄清楚问题是关于ada 2012功能,还是关于任何运行时错误,我试图插入一个与断言/合同无关的简单运行时错误:除以零。< / p>

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

并且在这种情况下,编译器告诉我将引发异常但在运行时程序完全终止但是打印出任何内容。 因此,问题出现在所有类型的运行时检查失败中,而不仅仅是那些与断言有关的问题。

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

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

非常感谢你的帮助。

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

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

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

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

如果要替换运行时中的文件,请将替换文件放在源代码中,并使用-a标志告诉gnatmake重新编译它和任何相关源。

答案 2 :(得分:0)

有与获取回溯信息相关的开关。来自documentation

-E     当目标支持时,在异常事件中存储回溯。有关更多信息,另请参阅GNAT.Traceback和GNAT.Traceback.Symbolic包。请注意,在x86端口上,不能使用-fomit-frame-pointer gcc选项。

我发现这是必须的。

答案 3 :(得分:0)

您是否有机会使用任务,并且该任务(然后以静默方式终止)发生异常,然后在出于非异常原因后立即终止该程序?

通常,由于异常而终止的任务将以静默方式执行(当您的任务中的其他异常处理程序帮助查看此任务时,您通常需要执行任务的顶部。)