prelic
prelic

Reputation: 4518

Catching Memory Exceptions in C Code From Ada

I have some ada code that interfaces with some C functions, and I am having trouble catching memory exceptions/SIGSEGV signals in the ada code that are generated/raised by the C code. I am using ada tasks which run the C functions, but the only way I know that there is a problem in the C code is that when I try to schedule more tasks, the ada code raises a TASKING_ERROR. This is okay, but it is impossible to figure out exactly where the problem came from, as the only indication of a problem is the TASKING_ERROR "all the way up" in my ada task scheduler. Any ideas of a strategy that I might employ to pinpoint the actual cause of the tasking errors?

Any help or ideas would be much appreciated.

Upvotes: 0

Views: 854

Answers (1)

Simon Wright
Simon Wright

Reputation: 25501

Try a last-chance exception handler in your task, compile with -g, and bind with -bargs -E (that is, if you're using gnatmake; otherwise, gnatbind -E).

With segv.c containing

void segv(void) {
  char *zero = 0;
  *zero = 0;
}

and

with Ada.Exceptions;
with Ada.Text_IO; use Ada.Text_IO;
procedure Call_Segv is
   task T;
   task body T is
      procedure Segv;
      pragma Import (C, Segv);
   begin
      Put_Line ("calling segv ...");
      Segv;
      Put_Line ("... done.");
   exception
      when E : others =>
         Put_Line ("... exception: "
                     & Ada.Exceptions.Exception_Information (E));
   end T;
begin
   null;
end Call_Segv;

building with

$ gnatmake call_segv.adb -g -bargs -E -largs segv.o -Wl,-no_pie

I get

$ call_segv
calling segv ...
... exception: Exception name: CONSTRAINT_ERROR
Message: erroneous memory access
Call stack traceback locations:
0x10002cea5 0x7fff8ff8a948 0x100002077 0x100002304 0x10000ef16 0x7fff8ff9c7a0

and the stack trace interprets as

$ atos -o call_segv 0x10002cea5 0x7fff8ff8a948 0x100002077 0x100002304 0x10000ef16 0x7fff8ff9c7a0
__gnat_error_handler (in call_segv) + 53
0x7fff8ff8a948
segv (in call_segv) (segv.c:3)
call_segv__tTKB.3158 (in call_segv) (call_segv.adb:10)
system__tasking__stages__task_wrapper (in call_segv) + 406
0x7fff8ff9c7a0

(that's on Mac OS X; on a more normal machine, you won't need the -Wl,-no_pie and you'll use addr2line instead of atos).

Upvotes: 4

Related Questions