comp.lang.ada
 help / color / mirror / Atom feed
From: "Thorsten" <thorsten.behrens@dorunth.de>
Subject: Interrupt handler seems not to be called in GNAT 3.15p
Date: 15 Jun 2005 08:39:01 -0700
Date: 2005-06-15T08:39:01-07:00	[thread overview]
Message-ID: <1118849941.554713.60100@g14g2000cwa.googlegroups.com> (raw)

Hi!

I'm currently writing a small package that does a memory dump in an
'od' like format. The program is compiled using GNTA 3.15p under Win2k,
but will be compiled with AdaMulti as well and shall later on run on a
special hardware.

When accessing memory, I might not have access to some memory location.
I've therefore implemented an interrupt handler to take care of
SIGSEGV. This, however, does not seem to be called - at least not under
Windows (I haven't tested on the target hardware yet, because it has to
run under Windows as well).

Running the program with gdb, I can see SIGSEGV being raised. However,
it is not passed to my interrupt handler, but causes the program to
terminate (as is the "normal" behaviour defined for SIGSEGV).

Here's some code snippets which to me seem quite OK ;-)

package body MONITOR is
  ...
  -- Definition of signal handler to react on SIGSEGV. The procedure
  -- HANDLE_SIGSEGV just sets the boolean variable and returns
  -- therafter to handle the interrupt with a minimum of time. Whether
  -- or not an interrupt occured can be checked with entry
  -- SIGSEGV_RAISED, which is callable then.
  protected SIGNAL_HANDLER is
    pragma UNRESERVE_ALL_INTERRUPTS;
    procedure HANDLE_SIGSEGV;
    pragma INTERRUPT_HANDLER(HANDLE_SIGSEGV);
    entry SIGSEGV_RAISED;
  private
    SIGSEGV_RECEIVED : BOOLEAN := FALSE;
  end SIGNAL_HANDLER;

  protected body SIGNAL_HANDLER is
    procedure HANDLE_SIGSEGV is
    begin
       SIGSEGV_RECEIVED := TRUE;
    end HANDLE_SIGSEGV;

    entry SIGSEGV_RAISED when SIGSEGV_RECEIVED is
    begin
      IO_PACKAGE.PUT_LINE("There was a SIGSEGV");
      SIGSEGV_RECEIVED := FALSE;
    end SIGSEGV_RAISED;
  end SIGNAL_HANDLER;

  ...

begin

  ...

  if not ATTACHED_SIGSEGV then
    if not ADA.INTERRUPTS.IS_RESERVED(SIGSEGV) then
      begin
        NEW_SIGSEGV_HANDLER := SIGNAL_HANDLER.HANDLE_SIGSEGV'ACCESS;
        ADA.INTERRUPTS.EXCHANGE_HANDLER(OLD_SIGSEGV_HANDLER,
                                        NEW_SIGSEGV_HANDLER,
                                        SIGSEGV);
        ATTACHED_SIGSEGV := TRUE;
      exception
        when THE_ERROR: PROGRAM_ERROR =>
          IO_PACKAGE.PUT_LINE
            ("SIGNAL_HANDLER installation: " &
             ADA.TEXT_IO.UTIL.LINE_TERMINATION_STRING &
             ADA.EXCEPTIONS.EXCEPTION_INFORMATION(THE_ERROR));
          raise;
      end;
    end if;
  end if;

  ...

  -- THE_BUFFER is an array of SYSTEM.STORAGE_ELEMENTs
  for I in THE_BUFFER'RANGE loop
  begin
    -- Access storage only once (i.e. THE_BUFFER(I) is only acessed
    -- here). We add this to the previous value of STORAGE_ELEMENT
    -- (which is 0 in case we format the output in bytes and may hold
    -- the values of upper (double)word(s) in other cases).
    STORAGE_ELEMENT := THE_BUFFER(I);

    -- Test, whether there was a segmentation violation when accessing
    -- memory. If it was, the entry of our signal handler is callable
    -- and we will set STORAGE_ELEMENT to 0. Otherwise everything is
    -- fine.
    select
      SIGNAL_HANDLER.SIGSEGV_RAISED;
      STORAGE_ELEMENT := 0;
    else
      null;
    end select;

  exception
    when THE_ERROR: others =>
      IO_PACKAGE.DEBUG("Exception " &
                       ADA.EXCEPTIONS.EXCEPTION_NAME(THE_ERROR) &
                       " is raised when accessing memory!");
      STORAGE_ELEMENT := 0;
  end;

  ...

end MONITOR;

When running the program SIGSEGV is raised twice (which I can see only
in gdb) for the same memory location and the program terminates. If I
put a delay 5.0 (or some other time) statement just before accessing
the memory, I also get the output of the exception handler, which
means an exception (PROGRAM_ERROR) is raised.

Can anyone give me a hint? Is this a known problem with GNAT 3.15p?
Is it possible to handle SIGSEGV at all in this environment?

Regards,
Thorsten




             reply	other threads:[~2005-06-15 15:39 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-15 15:39 Thorsten [this message]
2005-06-16  6:52 ` Interrupt handler seems not to be called in GNAT 3.15p David C. Hoos, Sr.
2005-06-16  7:38   ` Thorsten
2005-06-16  8:03 ` Egil H. H�vik
2005-06-16  9:36   ` Thorsten
2005-06-17  8:33 ` Thorsten
2005-06-17  8:47   ` Duncan Sands
2005-06-22 10:04     ` Thorsten
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox