comp.lang.ada
 help / color / mirror / Atom feed
* Interrupt handler seems not to be called in GNAT 3.15p
@ 2005-06-15 15:39 Thorsten
  2005-06-16  6:52 ` David C. Hoos, Sr.
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Thorsten @ 2005-06-15 15:39 UTC (permalink / 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




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-15 15:39 Interrupt handler seems not to be called in GNAT 3.15p Thorsten
@ 2005-06-16  6:52 ` David C. Hoos, Sr.
  2005-06-16  7:38   ` Thorsten
  2005-06-16  8:03 ` Egil H. H�vik
  2005-06-17  8:33 ` Thorsten
  2 siblings, 1 reply; 8+ messages in thread
From: David C. Hoos, Sr. @ 2005-06-16  6:52 UTC (permalink / raw)
  To: Thorsten; +Cc: comp.lang.ada

Did you use the pragma Unreserved_all_Interrupts?

See the discussion of that Pragma un the GNAT Reference Manual
----- Original Message ----- 
From: "Thorsten" <thorsten.behrens@dorunth.de>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada-france.org>
Sent: June 15, 2005 10:39 AM
Subject: Interrupt handler seems not to be called in GNAT 3.15p


> 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
> 
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada-france.org
> http://www.ada-france.org/mailman/listinfo/comp.lang.ada
> 
>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-16  6:52 ` David C. Hoos, Sr.
@ 2005-06-16  7:38   ` Thorsten
  0 siblings, 0 replies; 8+ messages in thread
From: Thorsten @ 2005-06-16  7:38 UTC (permalink / raw)


Hi David!

> Did you use the pragma Unreserved_all_Interrupts?

Yes, it is just in the first line of the specification of
SIGNAL_HANDLER.

> See the discussion of that Pragma un the GNAT Reference Manual

There it says that, after using pragma UNRESERVE_ALL_INTERRUPTS, my
program shall be able to handle this signal. I also took a look at
a-intnam.ads, where all interrupts, that may be handled by an
application, are defined with symbolic names. There is no hint
whatsoever why the application should not be able to handle SIGSEGV.

Regards,
Thorsten




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-15 15:39 Interrupt handler seems not to be called in GNAT 3.15p Thorsten
  2005-06-16  6:52 ` David C. Hoos, Sr.
@ 2005-06-16  8:03 ` Egil H. H�vik
  2005-06-16  9:36   ` Thorsten
  2005-06-17  8:33 ` Thorsten
  2 siblings, 1 reply; 8+ messages in thread
From: Egil H. H�vik @ 2005-06-16  8:03 UTC (permalink / raw)



> 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?


Have you looked at pragma Attach_Handler?

pragma Unreserve_All_Interrupts;
protected Handler is
   procedure Handle_SIGSEGV;
   pragma Attach_Handler( Handle_SIGSEGV, Ada.Interrupts.Names.SIGSEGV );
end Handler;


~egilhh





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-16  8:03 ` Egil H. H�vik
@ 2005-06-16  9:36   ` Thorsten
  0 siblings, 0 replies; 8+ messages in thread
From: Thorsten @ 2005-06-16  9:36 UTC (permalink / raw)


Hi Egil!

> Have you looked at pragma Attach_Handler?
>
> pragma Unreserve_All_Interrupts;
> protected Handler is
>    procedure Handle_SIGSEGV;
>    pragma Attach_Handler( Handle_SIGSEGV, Ada.Interrupts.Names.SIGSEGV );
> end Handler;

Yes, I also tried with a static signal handler. There is no difference
in behaviour.

I also tried with a task type insted of a protected object - which also
makes no difference.

Regards,
Thorsten




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-15 15:39 Interrupt handler seems not to be called in GNAT 3.15p Thorsten
  2005-06-16  6:52 ` David C. Hoos, Sr.
  2005-06-16  8:03 ` Egil H. H�vik
@ 2005-06-17  8:33 ` Thorsten
  2005-06-17  8:47   ` Duncan Sands
  2 siblings, 1 reply; 8+ messages in thread
From: Thorsten @ 2005-06-17  8:33 UTC (permalink / raw)


I did some further investigation on this: I added a boolean variable,
which is set when the exception handler within the
"for I in THE_BUFFER'range"-loop is called. If this is the case, I
exit the loop, print out some text to inform the user and everything
is fine.

However, as soon as the MONITOR.DUMP routine is called a second time
and gets an interrupt, the program terminates immediately. I.e. there
is no exception raised as was with the first call.

It seems to me the interrupt is still pending somewhere and as soon as
a second interrupt comes in, the program exits. Is this normal for
interrupts (I'm new on this field, so I don't know anything that may
be obvious to others)?

Regards,
Thorsten




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-17  8:33 ` Thorsten
@ 2005-06-17  8:47   ` Duncan Sands
  2005-06-22 10:04     ` Thorsten
  0 siblings, 1 reply; 8+ messages in thread
From: Duncan Sands @ 2005-06-17  8:47 UTC (permalink / raw)
  To: comp.lang.ada; +Cc: Thorsten

Did you try with gcc-4?  There were some interrupt handling bugs in
GNAT 3.15p IIRC.

Ciao,

D.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-17  8:47   ` Duncan Sands
@ 2005-06-22 10:04     ` Thorsten
  0 siblings, 0 replies; 8+ messages in thread
From: Thorsten @ 2005-06-22 10:04 UTC (permalink / raw)


Hi!

The problem is that I can't easily change the development environment
of the whole project.

I tried to install and integrate gcc-4.0.0 in a private area. Although
installing gcc-4.0.0 finally succeeded, I was not able to get it
working together GPS and GNAT.

Regards,
Thorsten




^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2005-06-22 10:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-15 15:39 Interrupt handler seems not to be called in GNAT 3.15p Thorsten
2005-06-16  6:52 ` 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

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