Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get Ada exception message when catching from C++ handler?

Using GNAT Ada and Gnu C++, I'm interfacing an Ada piece of code with a c++ wrapper and I'd like to catch Ada exceptions properly when running this (stupid) code:

with ada.text_io;

package body ada_throw is

   procedure ada_throw is
   begin
      ada.text_io.put_line ("hello");
      raise program_error;
   end ada_throw;       

end ada_throw;

relevant spec code is:

package ada_throw is

   procedure ada_throw;
   pragma export (convention => C, entity => ada_throw, external_name => "ada_throw");

end ada_throw;

Whe doing this on the C++ side:

#include <iostream>

extern "C"
{
  void ada_throw();
  void adainit();
}

int main()
{
  adainit();
  ada_throw();
  std::cout << "end of program" << std::endl;
  return 0;
}

I'm getting this:

hello

raised PROGRAM_ERROR : ada_throw.adb:8 explicit raise

So the exception mechanism works, I don't get the last print of my C++ program and the return code is non-zero.

Now I want to catch the exception. If I use catch(...) it works, but I can't get the explicit error message anymore, so I tried this:

#include <iostream>
#include <cxxabi.h>
extern "C"
{
  void ada_throw();
  void adainit();
}

int main()
{
  adainit();

  try
  {
    ada_throw();
  }
  catch (abi::__foreign_exception const &e)
  {
    std::cout << "exception" << std::endl;        
  }

  std::cout << "end of program" << std::endl;
  return 0;
}

it works properly, I get:

hello
exception
end of program

The only catch is that abi::__foreign_exception doesn't have a what() method, so I cannot get hold of the meaningful error message.

And debugging the program to try to hack into e is also a dead end since it's just a null pointer with the proper type:

(gdb) p &e
$2 = (const __cxxabiv1::__foreign_exception *) 0x0

Is there a way to get it from the C++ ?

like image 992
Jean-François Fabre Avatar asked May 21 '18 11:05

Jean-François Fabre


People also ask

How exception is handled in Ada with an example?

Standard Exceptions Basically, an exception in Ada can be raised, and it can be handled; information associated with an occurrence of an exception can be interrogated by a handler. Ada makes heavy use of exceptions especially for data consistency check failures at run time.

How is a user defined exception defined in Ada?

Ada gives the user the ability to define their own exceptions. These are placed in the declarative part of the code. They can be placed whereever a normal declaration is placed (e.g. even in package specifications).

What are the four exceptions defined in the standard package of Ada?

Exception handlers can be included in blocks or in the bodies of subprograms, packages, or tasks. 10. What are the four exceptions defined in the Standard package of Ada ? – Constraint_Error,Program_Error,Storage_Error, and Tasking_Error.


1 Answers

In Ada you can get information about an exception occurrence using the functions Ada.Exceptions.Exception_Name and Ada.Exceptions.Exception_Message, which are a part of the standard library. One option is to provide a thin binding to these two functions, and call them, when you need information about the exception. (Exactly how to map abi::__foreign_exception to Ada.Exceptions.Exception_ID is left as an exercise for the reader.)

Another option is to make it explicit to the Ada compiler that you are writing C++ on the other side, and use CPlusPlus instead of C as your export convention. That may make the compiler provide exceptions, which C++ understands.

This is only a partial answer, as I'm very much out of practice with C++, but I hope it can help you in the right direction.

like image 134
Jacob Sparre Andersen Avatar answered Sep 19 '22 05:09

Jacob Sparre Andersen