delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/10/03/03:02:12

Date: Thu, 3 Oct 1996 08:57:56 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: DJ Delorie <dj AT delorie DOT com>, Charles Sandmann <sandmann AT clio DOT rice DOT edu>
Cc: djgpp-workers AT delorie DOT com
Subject: Re: `abort' in nested programs
In-Reply-To: <199609291715.NAA00650@delorie.com>
Message-Id: <Pine.SUN.3.91.961003085139.27330B-100000@is>
Mime-Version: 1.0

On Sun, 29 Sep 1996, DJ Delorie wrote:

> > So the call to `atexit' on go32/dpmiexcp.c should be also undone.  I can 
> > submit the patches if necessary.
> 
> Correct, and a forced call put into _exit.

Here are the necessary patches to make a call to `abort' safe in nested
programs.  I also added a small test program to `abort.c' (which is
otherwise unchanged) so you can see the difference before and after
applying the patches. 

Since the original `_exit' was an assembly function on `crt0.s', I 
preferred not to mess with it; so I just renamed it to `__exit' 
(`___exit' in assembly) and added `_exit' to go32/dpmiexcp.c.  I 
understand that dpmiexcp is always linked in, so that shouldn't be a 
problem.  Am I right on this?

Charles, would you please also take a look at these changes to see if I 
didn't screw anything?  Thanks.

*** src/libc/crt0/crt0.s~0	Thu Jan 25 02:54:12 1996
--- src/libc/crt0/crt0.s	Wed Oct  2 10:36:46 1996
***************
*** 275,283 ****
  
  #define FREESEL(x) movw x, %bx; movw $0x0001, %ax; int $0x31
  
! 	.global	__exit
  	.align	2
! __exit:
  	movb	4(%esp), %al
  exit:
  	movb	%al, %cl
--- 275,283 ----
  
  #define FREESEL(x) movw x, %bx; movw $0x0001, %ax; int $0x31
  
! 	.global	___exit
  	.align	2
! ___exit:
  	movb	4(%esp), %al
  exit:
  	movb	%al, %cl
***************
*** 297,303 ****
  	int	$0x31			/* Free block and selector */
  #ifdef MULTIBLOCK
  9:	movl	___djgpp_memory_handle_pointer, %ebx
! 	movl	$__exit, %esp		/* We will free stack! Old init code as temp stack */
  	jmp	7f
  6:	subl	$8, %ebx
  	movl	(%ebx), %edi
--- 297,303 ----
  	int	$0x31			/* Free block and selector */
  #ifdef MULTIBLOCK
  9:	movl	___djgpp_memory_handle_pointer, %ebx
! 	movl	$___exit, %esp		/* We will free stack! Old init code as temp stack */
  	jmp	7f
  6:	subl	$8, %ebx
  	movl	(%ebx), %edi
*** src/libc/crt0/crt0.t~2	Tue Aug 13 19:20:38 1996
--- src/libc/crt0/crt0.txh	Wed Oct  2 11:23:00 1996
***************
*** 110,119 ****
  @subheading Description
  
  This function exits the program, returning @var{exit_code} to the
! calling process.  No additional processing is done, and any
! @code{atexit} functions are not called.  This function is normally
! called only by @code{exit}.  Since this does not unhook hardware 
! interrupts, this can cause crashes after the program exits.
  
  @subheading Return Value
  
--- 110,144 ----
  @subheading Description
  
  This function exits the program, returning @var{exit_code} to the
! calling process.  No additional processing (such as closing file
! descriptors or calls to the static destructor functions) is done, and
! any @code{atexit} functions are not called; only the hardware interrupt
! handlers are unhooked, to prevent system crashes e.g. after a call to
! @code{abort}.  This function is normally called only by @code{exit} and
! @code{abort}.
! 
! @subheading Return Value
! 
! This function does not return.
! 
! @c ----------------------------------------------------------------------
! @node __exit, process
! @subheading Syntax
! 
! @example
! #include <stdlib.h>
! 
! void __exit(int exit_code);
! @end example
! 
! @subheading Description
! 
! This is an internal library function which exits the program, returning
! @var{exit_code} to the calling process.  No additional processing is
! done, and any @code{atexit} functions are not called.  Since hardware
! interrupts are not unhooked, this can cause crashes after the program
! exits. This function is normally called only by @code{_exit}; do
! @emph{not} call it directly.
  
  @subheading Return Value
  
*** src/libc/go32/dpmiexcp.c~1	Sat May  4 19:09:44 1996
--- src/libc/go32/dpmiexcp.c	Wed Oct  2 10:32:42 1996
***************
*** 318,324 ****
    __dpmi_paddr except;
    __dpmi_meminfo lockmem;
    int i;
-   static int veryfirst = 1;
  
    for (i = 0; i < SIGMAX; i++)
      signal_list[i] = (SignalHandler)SIG_DFL;
--- 318,323 ----
***************
*** 358,367 ****
    __dpmi_get_protected_mode_interrupt_vector(9, &__djgpp_old_kbd);
    __djgpp_exception_toggle();	/* Set new values & save old values */
  
-   if (veryfirst) {
-     veryfirst = 0;
-     atexit(__djgpp_exception_toggle); /* Toggle at exit */
-   }
    /* get original video mode and save */
    old_video_mode = _farpeekb(_dos_ds, 0x449);
  }
--- 357,362 ----
***************
*** 375,378 ****
--- 370,386 ----
    else
      __djgpp_hwint_flags |= 1;
    return oldenable;
+ }
+ 
+ void __attribute__((noreturn))
+ _exit(int status)
+ {
+   /* We need to restore hardware interrupt handlers even if somebody calls
+      `_exit' directly, or else we crash the machine in nested programs.
+      We only toggle the handlers if the original keyboard handler is intact
+      (otherwise, they might have already toggled them).  */
+   if (__djgpp_old_kbd.offset32 == kbd_ori.offset32
+       && __djgpp_old_kbd.selector == kbd_ori.selector)
+     __djgpp_exception_toggle ();
+   __exit (status);
  }
*** src/libc/ansi/stdlib/abort.c~0	Thu Apr 13 09:21:48 1995
--- src/libc/ansi/stdlib/abort.c	Wed Oct  2 11:06:30 1996
***************
*** 11,13 ****
--- 11,51 ----
    _write(STDERR_FILENO, msg, sizeof(msg)-1);
    _exit(1);
  }
+ 
+ #ifdef TEST
+ 
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
+ #include <process.h>
+ #include <sys/exceptn.h>
+ 
+ int main (int argc, char *argv[])
+ {
+   int status = 0;
+ 
+   errno = 0;
+   if (argc > 1)
+     {
+       if (strcmp (argv[1], "abort") == 0)
+ 	abort ();
+       else if (strcmp (argv[1], "toggle") == 0)
+ 	{
+ 	  __djgpp_exception_toggle ();
+ 	  abort ();
+ 	}
+     }
+   else
+     {
+       fprintf (stderr, "\tType `%s abort RET'\n"
+ 		       "or\n"
+ 		       "\t     `%s toggle RET'\n", argv[0], argv[0]);
+       status = system ("");
+     }
+ 
+   fprintf (stderr, "Child returned %d\n", status);
+   if (errno)
+     perror ("spawn");
+   return 0;
+ }
+ #endif

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019