4

I'm developing a large project using the Ada language (around 10000 lines of only-code). During the use of the contract-base programming (Ada-2012 features like pre, post conditions, type invariants etc.) I find that when an Assertion or a condition goes wrong, the program terminates, hence the assertion has been checked, but without any messsage about the type and the place where the error is.

Then, to figure out if the problem was about the ada 2012 features, or instead, about any runtime error, I tried to insert a simple runtime error that doesn't concern with Assertions/Contracts: a division by zero.

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

and in this case the compiler advises me that will be raised an exception but at runtime the program completely terminates but anything is printed out. Hence the problem comes out with all kind of runtime check failure, not only those that concern with Assertions.

Moreover I tried to make a new project with only few lines of code to try a simple runtime error (as before division by zero) and also preconditions and Assertion failure. In this small project the program print on the consolle all the errors. Only the large project is affected by the problem.

My question is where could be the problem? Why this affects only my project and not the simple, just created, one? Could be there options that inhibit the printing of runtime check failure? I'm running on XUbuntu 13.10. I'm using the latest (2013) gpl version of gnat, gps, gnatcoll, aws, polyorb. I'm compiling with switches "-gnata" and "-gnat12".

Thanks very much for the help.

  • I have a feeling "pragma assertion_policy" and this page http://www.ada-auth.org/standards/12aarm/html/AA-11-4-2.html may be relevant –  Jan 28 '14 at 12:43
  • Here's a cleaner link to 11.4.2: http://www.ada-auth.org/standards/12rm/html/RM-11-4-2.html. – Marc C Jan 28 '14 at 13:15
  • I edited the post because I didn't explain the problem properly. The problem is about ALL the runtime errors, not only those about Assertions. The Assertions ARE CHECKED, but nothing is printed out on the consolle. (I'm compiling with the switch "-gnata". It turn on all the Assertion check). – Andrea Gardiman Jan 28 '14 at 13:28
  • 1
    Does Ada.Text_IO work? to Standard_Output? to Standard_Error? What about GNAT.IO? (I don’t know what mechanism GNAT uses for error reports). – Simon Wright Jan 28 '14 at 17:15
  • If I use GNAT.IO.Put_Line or Ada.Text_IO.Put_Line they print properly on the consolle. Sorry, but I didn't understand what do you mean for "to Standard_Output", "to Standard_Error" and for "about GNAT.IO"? @SimonWright – Andrea Gardiman Jan 28 '14 at 17:32
  • On Unix boxes (I don’t know about Windows) there are two predefined [standard streams](http://en.wikipedia.org/wiki/Standard_streams) for output, standard output (stdout) for normal stuff, standard error (stderr) for error messages. I wondered whether one of them might have got closed. I see both GNAT.IO and Ada.Text_IO support stderr: `GNAT.IO.Put_Line (GNAT.IO.Standard_Error, “foo”);`, for example. Trying to write to a closed stream would be an error and of course you wouldn’t see it! – Simon Wright Jan 28 '14 at 21:43
  • 1
    @SimonWright the error stream is opened because trying your suggestion the string was printed properly. – Andrea Gardiman Jan 30 '14 at 16:29

4 Answers4

3

If you want to use GNAT as a proper Ada compiler, you should as an absolute minimum pass it these arguments:

  • "-fstack-check", -- Generate stack checking code (part of Ada)
  • "-gnata", -- Enable assertions (part of Ada)
  • "-gnato", -- Overflow checking (part of Ada)

Personally I have written this project file, which I use to set my preferred arguments to 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;

I "with" this file in all my Ada (2012) project files to have easy access to my standard settings. Here is an example (from 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;
Jacob Sparre Andersen
  • 6,733
  • 17
  • 22
  • 1
    With [ada-mode 5](http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html#ada-mode-5.0), there is a gpr-mode. – Simon Wright Jan 29 '14 at 10:14
  • You could also add -gnateE - this will include additional information printed by uncaught exception. – darkestkhan Jan 29 '14 at 12:22
  • Also with all these switches the problem is still there. Within the large project every runtime error is checked, raised, but doesn't print anything. Contrariwise the small one (created specifically for this purpose. It contains only few lines of code to raise a runtime error) prints ALL runtime errors. – Andrea Gardiman Jan 30 '14 at 16:35
3

It seems to me most likely that something in your program is breaking GNAT’s mechanism for printing out the message you’d normally get for an unhandled exception.

This is done (in GCC 4.8.1, and as far as I can tell in GNAT GPL 2013) in Ada.Exceptions.Last_Chance_Handler, in file a-elchha.adb. The printing is done via stderr after some closedown stuff; you might try replacing the standard last chance handler with something that gives you more opportunity to investigate.

Alternatively, could you use the debugger? I believe you can tell GDB catch exception unhandled which should help.

If you want to replace a file in the runtime, put the replacement with your source code and use the -a flag to tell gnatmake to recompile it and any dependent sources.

Simon Wright
  • 25,108
  • 2
  • 35
  • 62
1

Any chance you are using tasks, and the exception is happening in a task (which then silently terminates) with the program then terminating shortly after for a non-exception reason?

In general, tasks that terminate due to exception will do so silently (you'd generally want a top of the task when others exception handler in your tasks to help see this).

Jeff_NH
  • 11
  • 1
0

There are switches related to getting backtrace information. From the documentation:

-E Store tracebacks in exception occurrences when the target supports it. See also the packages GNAT.Traceback and GNAT.Traceback.Symbolic for more information. Note that on x86 ports, you must not use -fomit-frame-pointer gcc option.

I find that a must.

Álex
  • 1,587
  • 11
  • 17