From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,c2650880fba54b9e,start X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!g14g2000cwa.googlegroups.com!not-for-mail From: "Thorsten" Newsgroups: comp.lang.ada Subject: Interrupt handler seems not to be called in GNAT 3.15p Date: 15 Jun 2005 08:39:01 -0700 Organization: http://groups.google.com Message-ID: <1118849941.554713.60100@g14g2000cwa.googlegroups.com> NNTP-Posting-Host: 195.226.123.200 Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Trace: posting.google.com 1118849946 28619 127.0.0.1 (15 Jun 2005 15:39:06 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Wed, 15 Jun 2005 15:39:06 +0000 (UTC) User-Agent: G2/0.2 Complaints-To: groups-abuse@google.com Injection-Info: g14g2000cwa.googlegroups.com; posting-host=195.226.123.200; posting-account=jGHaLA0AAAANZvivCTObYBZ3awmy43dc Xref: g2news1.google.com comp.lang.ada:11379 Date: 2005-06-15T08:39:01-07:00 List-Id: 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