public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* egcs 10-31 and UnixWare
@ 1997-11-07  9:25 acs
  1997-11-09 10:14 ` Jeffrey A Law
  0 siblings, 1 reply; 13+ messages in thread
From: acs @ 1997-11-07  9:25 UTC (permalink / raw)
  To: egcs, gcc2; +Cc: Ronald Joe Record, Robert Lipe

I still can't build the recent egcs snapshots on UnixWare 2.1.2 (SVR4.2 MP).
The most recent snapshot I successfully built was egcs-970910.  I have tried 
many snapshots since then, including 10-31 and 11-05 and they all fail in 
the same way: the stage 1 compiler builds an executable which dumps core in
__do_global_dtors_aux() on the way out.

(testgcc-971104 fails in the same way, so I've included gcc2 in the 
distribution list.)


Here's the backtrace:
#0  0xbffb3783 in kill ()
#1  0xbffe3528 in abort ()
#2  0x804853e in __do_global_dtors_aux ()
#3  0x8048ffd in _fini ()

(See http://www.cygnus.com/ml/egcs/1997-Oct/1099.html for more info.)

The failure comes from crtend.o.  I'm trying to figure out what's going on
there, but I could use some pointers in how to debug it; gdb claims there is
no source information available for crtend.o.

BTW, I notice that crtstuff.c (progenitor of crtend.o) changed between 
970910 and the newer snapshots to include a bunch of exception handling 
code.  (I mention this in case it jogs anyone's memory.)  I also notice 
that crtstuff.c is now identical between egcs and testgcc-971104.

Any hints/suggestions/reminders are welcome.

thanks,
  vin shelton


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

* Re: egcs 10-31 and UnixWare
  1997-11-07  9:25 egcs 10-31 and UnixWare acs
@ 1997-11-09 10:14 ` Jeffrey A Law
  1997-11-09 11:16   ` Robert Lipe
  0 siblings, 1 reply; 13+ messages in thread
From: Jeffrey A Law @ 1997-11-09 10:14 UTC (permalink / raw)
  To: acs; +Cc: egcs, gcc2, Ronald Joe Record, Robert Lipe

  In message < 199711071702.MAA14022@honeydew.icd.teradyne.com >you write:
  > I still can't build the recent egcs snapshots on UnixWare 2.1.2 (SVR4.2 MP).
  > The most recent snapshot I successfully built was egcs-970910.  I have tried 
  > many snapshots since then, including 10-31 and 11-05 and they all fail in 
  > the same way: the stage 1 compiler builds an executable which dumps core in
  > __do_global_dtors_aux() on the way out.
Hmm, I must have missed something -- I thought we were getting screwed up
on the way in!


If we're indeed dying on the exit path, then I'd start to look at some of
the problems Robert Lipe recently ran into.


  > Here's the backtrace:
  > #0  0xbffb3783 in kill ()
  > #1  0xbffe3528 in abort ()
  > #2  0x804853e in __do_global_dtors_aux ()
  > #3  0x8048ffd in _fini ()
Can you do something like

x/50i __do_global_dtors_aux


Basically I don't see how the __do_global_dtors_aux routine from gcc's
crtstuff.c can call abort -- unless abort is on the dtor list.  So I'm
wondering if you're getting the correct crtbegin.o file.

Or maybe gdb is lying and you called abort from __deregister_frame which
would indicate that the exception handlers never got registered in the
first place or were clobbered.


Can you compile frame.c with debug symbols, add it to libgcc, then put
a breakpoint in __deregister_frame to see what's going on?


jeff

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

* Re: egcs 10-31 and UnixWare
  1997-11-09 10:14 ` Jeffrey A Law
@ 1997-11-09 11:16   ` Robert Lipe
  1997-11-09 13:49     ` Jeffrey A Law
  0 siblings, 1 reply; 13+ messages in thread
From: Robert Lipe @ 1997-11-09 11:16 UTC (permalink / raw)
  To: law; +Cc: acs, egcs, gcc2, Ronald Joe Record

Given the similarity in the symptoms and the environments, I 
suspect that the Unixware and OpenServer problems are related.

I don't know why he's getting nailed with it on every executable
and I'm only getting hammered in one test case, though.

>   > Here's the backtrace:
>   > #0  0xbffb3783 in kill ()
>   > #1  0xbffe3528 in abort ()
>   > #2  0x804853e in __do_global_dtors_aux ()
>   > #3  0x8048ffd in _fini ()
> Can you do something like
> 
> x/50i __do_global_dtors_aux
> 
> 
> Basically I don't see how the __do_global_dtors_aux routine from gcc's
> crtstuff.c can call abort -- unless abort is on the dtor list.  So I'm
> wondering if you're getting the correct crtbegin.o file.

Abort isn't on the dtor list in my case, but I"m starting to 
really distrust GDB here.   According to a print __DTOR_LIST__[1],
I don't have a dtor list, clearly there are destructors running.

> Or maybe gdb is lying and you called abort from __deregister_frame which
> would indicate that the exception handlers never got registered in the
> first place or were clobbered.

What if exit() is recursing?  

$ gdb a.out
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.14-95q4 (i486-unknown-sco3.2v5.0.0elf),
Copyright 1995 Free Software Foundation, Inc...
Breakpoint 1 at 0x80484b8
(gdb) break exit
Breakpoint 2 at 0x8048498
(gdb) break __do_global_dtors_aux
Breakpoint 3 at 0x80485a6
(gdb) break __deregister_frame
Breakpoint 4 at 0x8048e24
(gdb) run
Starting program: /home/play/ss/a.out
Breakpoint 1 at 0x8003ded9
Breakpoint 2 at 0x800196c4
++count
++count
Base
--count

Breakpoint 2, 0x800196c4 in exit ()
(gdb) cont
Continuing.

Breakpoint 3, 0x80485a6 in __do_global_dtors_aux ()
(gdb) cont
Continuing.
--count
--count

Breakpoint 2, 0x800196c4 in exit ()
(gdb) cont
Continuing.

Breakpoint 1, 0x8003ded9 in abort ()
(gdb)

This can't be good.

Hmmm.   Sure enough.  If I change the "exit 0" in the p9732b
program I'd just sent to "_exit 0", it works even with the 
HAVE_ATEXIT.    


> Can you compile frame.c with debug symbols, add it to libgcc, then put
> a breakpoint in __deregister_frame to see what's going on?

My breakpoint on __deregister_frame never gets called.

RJL

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

* Re: egcs 10-31 and UnixWare
  1997-11-09 13:49     ` Jeffrey A Law
@ 1997-11-09 12:35       ` acs
  1997-11-09 13:00       ` Robert Lipe
  1 sibling, 0 replies; 13+ messages in thread
From: acs @ 1997-11-09 12:35 UTC (permalink / raw)
  To: egcs, gcc2, Robert Lipe

Disclaimer: I am not sitting at my UnixWare box right now, however:

law@hurl.cygnus.com said:
>  Hmmm, maybe EH_FRAME_SECTION_ASM_OP isn't defined, and
> do_global_dtors_aux is actually finishing, which would drop us back
> into our friend fini_dummy. 

I believe that this is what I saw when I ran the code through the
preprocessor with the relevant symbols defined: it looked to me that
EH_FRAME_SECTION_ASM_OP wasn't defined.  When I was in gdb, it looked to me 
like we ended up in __do_global_dtors_aux twice, and the 2nd time through 
we dropped core.

HTH,
  vin



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

* Re: egcs 10-31 and UnixWare
  1997-11-09 13:49     ` Jeffrey A Law
  1997-11-09 12:35       ` acs
@ 1997-11-09 13:00       ` Robert Lipe
  1997-11-09 17:00         ` Jeffrey A Law
  1 sibling, 1 reply; 13+ messages in thread
From: Robert Lipe @ 1997-11-09 13:00 UTC (permalink / raw)
  To: law; +Cc: acs, egcs, gcc2, Ronald Joe Record

>   > Breakpoint 2, 0x800196c4 in exit ()
>   > (gdb) cont
>   > Continuing.
>   > 
>   > Breakpoint 3, 0x80485a6 in __do_global_dtors_aux ()
>   > (gdb) cont
>   > Continuing.
>   > --count
>   > --count
>   > 
>   > Breakpoint 2, 0x800196c4 in exit ()
>   > (gdb) cont
>   > Continuing.
> Wild.  That shouldn't be happening....  I think we've got something
> to work backwards from now.

I didn't think so. :-)

> What about recompiling the crt* files with -g -O0 so you can get
> control of do_global_dtors_aux and possibly see how in the hell
> it's calling exit!


> Hmmm, maybe EH_FRAME_SECTION_ASM_OP isn't defined, and do_global_dtors_aux
> is actually finishing, which would drop us back into our friend fini_dummy.

It's definitely defined on OpenServer.  When I disassemble
the binary, I can see the call to __de


08048580 <__do_global_dtors_aux>:
 8048580:       55              pushl  %ebp
 8048581:       8b ec           movl   %esp,%ebp
 8048583:       53              pushl  %ebx
 8048584:       e8 00 00 00 00  call   8048589 <__do_global_dtors_aux+9>
 8048589:       5b              popl   %ebx
 804858a:       81 c3 fb 20 00  addl   $0x20fb,%ebx
 804858f:       00
 8048590:       eb 15           jmp    80485a7 <__do_global_dtors_aux+27>
 8048592:       8b ff           movl   %edi,%edi
 8048594:       8b 83 94 fa ff  movl   0xfffffa94(%ebx),%eax
 8048599:       ff
 804859a:       8d 50 04        leal   0x4(%eax),%edx
 804859d:       89 93 94 fa ff  movl   %edx,0xfffffa94(%ebx)
 80485a2:       ff
 80485a3:       8b 00           movl   (%eax),%eax
 80485a5:       ff d0           call   *%eax
 80485a7:       8b 83 94 fa ff  movl   0xfffffa94(%ebx),%eax
 80485ac:       ff
 80485ad:       83 38 00        cmpl   $0x0,(%eax)
 80485b0:       75 e2           jne    8048594 <__do_global_dtors_aux+14>
 80485b2:       8d 83 c4 fa ff  leal   0xfffffac4(%ebx),%eax
 80485b7:       ff
 80485b8:       50              pushl  %eax
 80485b9:       e8 f2 08 00 00  call   8048eb0 <__deregister_frame>
 80485be:       8b 5d fc        movl   0xfffffffc(%ebp),%ebx
 80485c1:       8b e5           movl   %ebp,%esp
 80485c3:       5d              popl   %ebp
 80485c4:       c3              ret
 80485c5:       8d 76 00        leal   0x0(%esi),%esi

It's a little wierd that there's an opcode after the ret.

I don't think it's falling through.  It looks like the problem is that
we're in an atexit() function (__do_global_dtors_aux) and it's calling 
the destructor and the destructor is calling exit.   Since exit() will
rip through the atexit() functions, isn't this bad?


Currently, the makefile generates these files liek this:

./xgcc -B./  -DIN_GCC    -O2 -g -I./include  -I. -I../../egcs-971023/gcc -I../..
/egcs-971023/gcc/config  -g0 \
  -finhibit-size-directive -fno-inline-functions -fno-exceptions  \
  -c ../../egcs-971023/gcc/crtstuff.c -DCRT_BEGIN -o crtbegin.o
./xgcc -B./  -DIN_GCC    -O2 -g -I./include  -I. -I../../egcs-971023/gcc -I../..
/egcs-971023/gcc/config  -g0 \
  -finhibit-size-directive -fno-inline-functions -fno-exceptions  \
  -c ../../egcs-971023/gcc/crtstuff.c -DCRT_END -o crtend.o


begin slight tangent...

If I change '-g0' to '-g', it dies during the build:

./xgcc -B./  -DIN_GCC    -O2 -g -I./include  -I. -I../../egcs-971023/gcc -I../..
/egcs-971023/gcc/config  -g \
  -finhibit-size-directive -fno-inline-functions -fno-exceptions  \
  -c ../../egcs-971023/gcc/crtstuff.c -DCRT_BEGIN -o crtbegin.o
/usr/tmp/cca003Pz.s:279:defined relocatable values from the same section require
d, op -
/usr/tmp/cca003Pz.s:287:defined relocatable values from the same section require
d, op -
/usr/tmp/cca003Pz.s:410:defined relocatable values from the same section require
d, op -
/usr/tmp/cca003Pz.s:418:defined relocatable values from the same section require
d, op -


If also I change BOOT_CFLAGS to -O0, it makes no difference.

Looking at the assembly file, it's croaking  on the references to L_text_b
        .section        .line
        .4byte  148     / /crtstuff.c:148
        .2byte  0xffff
        .4byte  .L_LC12-.L_text_b
        .previous
        call __do_global_dtors_aux
.L_LC13:

L_text_b. is in the section .debug_aranges, .L_LC12 is in .text.
This seems to happen in the calls to asm(FINI_SECTION_ASM_OP)

If I run -g to -g1, it builds.



...end debug tangent.

Building crtstuff with this level of debugging makes the 
backtrace more clearly frightening.


Program received signal SIGABRT, Aborted.
0x80019733 in _kill ()
(gdb) where
#0  0x80019733 in _kill ()
#1  0x8003df84 in abort ()
#2  0x8001d46f in _exithandle ()
#3  0x8003df56 in abort ()
#4  0x8001d46f in _exithandle ()
#5  0x800196d6 in exit ()
#6  0x80485a7 in __do_global_dtors_aux ()
#7  0x804905d in .fini ()
#8  0x800196d6 in exit ()


RJL

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

* Re: egcs 10-31 and UnixWare
  1997-11-09 11:16   ` Robert Lipe
@ 1997-11-09 13:49     ` Jeffrey A Law
  1997-11-09 12:35       ` acs
  1997-11-09 13:00       ` Robert Lipe
  0 siblings, 2 replies; 13+ messages in thread
From: Jeffrey A Law @ 1997-11-09 13:49 UTC (permalink / raw)
  To: Robert Lipe; +Cc: acs, egcs, gcc2, Ronald Joe Record

  In message < 19971109131009.64698@dgii.com >you write:
  > Given the similarity in the symptoms and the environments, I 
  > suspect that the Unixware and OpenServer problems are related.
Yup.  That's why I suggested the Unixware folks talk to you :-)

  > > Basically I don't see how the __do_global_dtors_aux routine from gcc's
  > > crtstuff.c can call abort -- unless abort is on the dtor list.  So I'm
  > > wondering if you're getting the correct crtbegin.o file.
  > 
  > Abort isn't on the dtor list in my case, but I"m starting to 
  > really distrust GDB here.   According to a print __DTOR_LIST__[1],
  > I don't have a dtor list, clearly there are destructors running.
I never trust backtraces or other frame stuff if the program was compiled
with optimization -- unless _I_ did the gdb port.

  > > Or maybe gdb is lying and you called abort from __deregister_frame which
  > > would indicate that the exception handlers never got registered in the
  > > first place or were clobbered.
  > 
  > What if exit() is recursing?  
Hmmm.  Interesting question.

  > Breakpoint 2, 0x800196c4 in exit ()
  > (gdb) cont
  > Continuing.
  > 
  > Breakpoint 3, 0x80485a6 in __do_global_dtors_aux ()
  > (gdb) cont
  > Continuing.
  > --count
  > --count
  > 
  > Breakpoint 2, 0x800196c4 in exit ()
  > (gdb) cont
  > Continuing.
Wild.  That shouldn't be happening....  I think we've got something
to work backwards from now.

  > > Can you compile frame.c with debug symbols, add it to libgcc, then put
  > > a breakpoint in __deregister_frame to see what's going on?
  > 
  > My breakpoint on __deregister_frame never gets called.
What about recompiling the crt* files with -g -O0 so you can get
control of do_global_dtors_aux and possibly see how in the hell
it's calling exit!

Hmmm, maybe EH_FRAME_SECTION_ASM_OP isn't defined, and do_global_dtors_aux
is actually finishing, which would drop us back into our friend fini_dummy.

jeff

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

* Re: egcs 10-31 and UnixWare
  1997-11-09 13:00       ` Robert Lipe
@ 1997-11-09 17:00         ` Jeffrey A Law
  1997-11-09 18:35           ` Joe Buck
  1997-11-09 20:32           ` Robert Lipe
  0 siblings, 2 replies; 13+ messages in thread
From: Jeffrey A Law @ 1997-11-09 17:00 UTC (permalink / raw)
  To: Robert Lipe; +Cc: acs, egcs, gcc2, Ronald Joe Record

  In message < 19971109145838.26288@dgii.com >you write:
  > It's definitely defined on OpenServer.  When I disassemble
  > the binary, I can see the call to __de
OK.  'twas just a thought.

  > I don't think it's falling through.  It looks like the problem is that
  > we're in an atexit() function (__do_global_dtors_aux) and it's calling 
  > the destructor and the destructor is calling exit.   Since exit() will
  > rip through the atexit() functions, isn't this bad?
Hmmm, I don't know enough about the language to know how this is supposed
to be handled.

Anyone know what's supposed to happen if, while running global dtors
a dtor itself calls exit, which starts the process of runing global
dtors again....


  > begin slight tangent...
  > 
  > If I change '-g0' to '-g', it dies during the build:
  > 
  > ./xgcc -B./  -DIN_GCC    -O2 -g -I./include  -I. -I../../egcs-971023/gcc -I
  > ../..
  > /egcs-971023/gcc/config  -g \
  >   -finhibit-size-directive -fno-inline-functions -fno-exceptions  \
  >   -c ../../egcs-971023/gcc/crtstuff.c -DCRT_BEGIN -o crtbegin.o
  > /usr/tmp/cca003Pz.s:279:defined relocatable values from the same section re > quired, op -
Bummer.  I suspect this is the funky way it we switch sections under
gcc's nose in crtstuff.

Almost makes we wonder if we should be using section attributes to do
the switching (which gcc knows how to emit proper debug symbols for).


  > Building crtstuff with this level of debugging makes the 
  > backtrace more clearly frightening.
Assuming (of course) that gdb is telling us the truth.  The reason
I say that is __do_lobal_dtors_aux doesn't directly call exit 
(unless it's on the dtor list).  If it's being called from an object's
dtor, then we know that gdb's lying because frames are missing.

But I think you've hit the root of the problem -- it looks like we're
calling exit more than once, which seems to do bad things.


jeff

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

* Re: egcs 10-31 and UnixWare
  1997-11-09 17:00         ` Jeffrey A Law
@ 1997-11-09 18:35           ` Joe Buck
  1997-11-09 21:08             ` Joern Rennecke
  1997-11-09 20:32           ` Robert Lipe
  1 sibling, 1 reply; 13+ messages in thread
From: Joe Buck @ 1997-11-09 18:35 UTC (permalink / raw)
  To: law; +Cc: robertl, acs, egcs, gcc2, rr

> Anyone know what's supposed to happen if, while running global dtors
> a dtor itself calls exit, which starts the process of runing global
> dtors again....

I've read the relevant part of CD2 [lib.support.start.term] and that
isn't made clear: the description omits describing what happens on
a recursive call.  The other case where this kind of recursion occurs
(a destructor that is called as part of exception processing throws
an exception), the program is aborted by calling terminate().

Has the committee clarified this?  I can think of two logical ways
to proceed: call terminate(), or ignore the second exit() call.



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

* Re: egcs 10-31 and UnixWare
  1997-11-09 17:00         ` Jeffrey A Law
  1997-11-09 18:35           ` Joe Buck
@ 1997-11-09 20:32           ` Robert Lipe
  1997-11-10 14:57             ` H.J. Lu
  1 sibling, 1 reply; 13+ messages in thread
From: Robert Lipe @ 1997-11-09 20:32 UTC (permalink / raw)
  To: law; +Cc: acs, egcs, gcc2, Ronald Joe Record

>   > I don't think it's falling through.  It looks like the problem is that
>   > we're in an atexit() function (__do_global_dtors_aux) and it's calling 
>   > the destructor and the destructor is calling exit.   Since exit() will
>   > rip through the atexit() functions, isn't this bad?
> Hmmm, I don't know enough about the language to know how this is supposed
> to be handled.

I can see this as a grey area.     Can anyone cite definitive sources
for expected behaviour?

>   > /usr/tmp/cca003Pz.s:279:defined relocatable values from the same section re > quired, op -
> Bummer.  I suspect this is the funky way it we switch sections under
> gcc's nose in crtstuff.
> 
> Almost makes we wonder if we should be using section attributes to do
> the switching (which gcc knows how to emit proper debug symbols for).

If this is important, we can move this aspect to another thread.
It was just an annoyance I thought I'd mention.

> But I think you've hit the root of the problem -- it looks like we're
> calling exit more than once, which seems to do bad things.

Yes, and this is why removing HAVE_ATEXIT from my target made
the test case pass becuase we weren't calling exit more than
once.

The attached program does different things on the three systems
I tried it on.

OpenServer 5: $   Calls two.   Calls one.  Calls exit.  Calls abort.
Solaris 2.3:   Calls two.   Calls one.   Terminates normally. Exit val 1.
Redhat 4.1/x86: Calls two.   Calls one.  Calls two.  Call two.  Repeats
	until stack size hits 8Mb ulimit.  Faults.


If we decide that calling exit() from a destructor really is a 
questionable idea, we can just change the test case to call _exit()
instead of exit() in the destructor and we can put HAVE_ATEXIT back
in sco5.h.  

Now exactly how this ties into the Unixware stuff at this point,
I'm unsure...



#include <stdio.h>
#include <stdlib.h>

void one(void)
{
        printf("One\n");
        exit(1);
}

void two(void)
{
        printf("two\n");
}


int main(void)
{
        atexit(one);
        atexit(two);
        exit(1);
}


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

* Re: egcs 10-31 and UnixWare
  1997-11-09 18:35           ` Joe Buck
@ 1997-11-09 21:08             ` Joern Rennecke
  0 siblings, 0 replies; 13+ messages in thread
From: Joern Rennecke @ 1997-11-09 21:08 UTC (permalink / raw)
  To: Joe Buck; +Cc: law, robertl, acs, egcs, gcc2, rr

> Has the committee clarified this?  I can think of two logical ways
> to proceed: call terminate(), or ignore the second exit() call.

I can think of yet another: finish processing the current destructor,
but continue with the remaining ones.  There are two obvious ways
to implement it:

 - set a flag when destructor processing begins, make a setjmp
  in the loop that processes the destructors, and when there is
  an exit() recursion, do a longjmp.

- use (a) non-local variable(s) to interate through the destructors,
and allow full recursion of exit, but arrange the processing of the
iteration variables so that the next destructor will be picked as the
first one in the recursive call.

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

* Re: egcs 10-31 and UnixWare
  1997-11-10 14:57               ` Robert Lipe
@ 1997-11-10 12:27                 ` H.J. Lu
  0 siblings, 0 replies; 13+ messages in thread
From: H.J. Lu @ 1997-11-10 12:27 UTC (permalink / raw)
  To: Robert Lipe; +Cc: acs, egcs, gcc2, rr

> > I got the same result as Linux on Windows NT 4.0 with VC++ 5.0.
> > However I can change Linux to whatever behaviorw which makes
> > more senses.
> > 
> > How about call everyone on the list and use the status in the
> > last exit () call? BTW, it seems to be what happens on Solaris.
> 
> I'll leave that to you, H.J.  
> 

The patch is very trivial. I am enclosing one here for libc 5 in
case that anyone cares. I have sent a similar one to glibc 2.


H.J.
--
Index: stdlib/exit.c
===================================================================
RCS file: /home/work/cvs/linux/libc/stdlib/exit.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 exit.c
--- exit.c	1995/02/18 05:33:30	1.1.1.1
+++ exit.c	1997/11/10 19:44:51
@@ -36,14 +36,12 @@
 void
 DEFUN(exit, (status), int status)
 {
-  register CONST struct exit_function_list *l;
-
-  for (l = __exit_funcs; l != NULL; l = l->next)
+  for (; __exit_funcs; __exit_funcs = __exit_funcs->next)
     {
-      register size_t i = l->idx;
-      while (i-- > 0)
+      while ((__exit_funcs->idx)-- > 0)
 	{
-	  CONST struct exit_function *CONST f = &l->fns[i];
+	  CONST struct exit_function *CONST f
+		= &__exit_funcs->fns[__exit_funcs->idx];
 	  switch (f->flavor)
 	    {
 	    case ef_free:

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

* Re: egcs 10-31 and UnixWare
  1997-11-10 14:57             ` H.J. Lu
@ 1997-11-10 14:57               ` Robert Lipe
  1997-11-10 12:27                 ` H.J. Lu
  0 siblings, 1 reply; 13+ messages in thread
From: Robert Lipe @ 1997-11-10 14:57 UTC (permalink / raw)
  To: acs, egcs, gcc2, rr

[ Re: Program calling exit() in a function registered via atexit() ] 

I asked one of the SCO engineers about this, and he confirms the 
behaviour is as we suspected, though it is changed in future versions.

He offered:

	Regarding the standard, the behavior is undefined when a
	program calls exit() from an atexit()-registered function:

		"If more than one call to the exit function is
		 executed by a program, the behavior is undefined."

	in the description of exit in the current C standard.

I don't see this in my copy of Plauger's C library spec or in 
SUSv2, but it's certainly believable.

> > Redhat 4.1/x86: Calls two.   Calls one.  Calls two.  Call two.  Repeats
> > 	until stack size hits 8Mb ulimit.  Faults.
> 
> I got the same result as Linux on Windows NT 4.0 with VC++ 5.0.
> However I can change Linux to whatever behaviorw which makes
> more senses.
> 
> How about call everyone on the list and use the status in the
> last exit () call? BTW, it seems to be what happens on Solaris.

I'll leave that to you, H.J.  

I think the OpenServer (which calls abort() in this case, grrr..)
option is to remove HAVE_ATEXIT from sco5.h and let the dtors be 
run via .fini instead of via an exit callback.   This I did in my
recent patch to gcc2 and egcs.  


Alternately, should we discourage (disallow?) calling exit()
from destructors?    If so, just changing the exit() in the
testcase in question to _exit() would sidestep the issue for
the testcase, thought it might still be an issue for the Real 
World.   Of course, if Linux and the other two OSes that H.J.
cited are indicative of the Real World, nobody does this 
anyway....

It seems like loophole to restrain global destructors based on
undefined behaviour in atexit() when the programmer didn't call
atexit() - we used atexit() behind his back.

From here, the language lawyers in the group can duke it out. :-)

RJL

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

* Re: egcs 10-31 and UnixWare
  1997-11-09 20:32           ` Robert Lipe
@ 1997-11-10 14:57             ` H.J. Lu
  1997-11-10 14:57               ` Robert Lipe
  0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 1997-11-10 14:57 UTC (permalink / raw)
  To: Robert Lipe; +Cc: law, acs, egcs, gcc2, rr

> 
> >   > I don't think it's falling through.  It looks like the problem is that
> >   > we're in an atexit() function (__do_global_dtors_aux) and it's calling 
> >   > the destructor and the destructor is calling exit.   Since exit() will
> >   > rip through the atexit() functions, isn't this bad?
> > Hmmm, I don't know enough about the language to know how this is supposed
> > to be handled.
> 
> I can see this as a grey area.     Can anyone cite definitive sources
> for expected behaviour?
> 
> >   > /usr/tmp/cca003Pz.s:279:defined relocatable values from the same section re > quired, op -
> > Bummer.  I suspect this is the funky way it we switch sections under
> > gcc's nose in crtstuff.
> > 
> > Almost makes we wonder if we should be using section attributes to do
> > the switching (which gcc knows how to emit proper debug symbols for).
> 
> If this is important, we can move this aspect to another thread.
> It was just an annoyance I thought I'd mention.
> 
> > But I think you've hit the root of the problem -- it looks like we're
> > calling exit more than once, which seems to do bad things.
> 
> Yes, and this is why removing HAVE_ATEXIT from my target made
> the test case pass becuase we weren't calling exit more than
> once.
> 
> The attached program does different things on the three systems
> I tried it on.
> 
> OpenServer 5: $   Calls two.   Calls one.  Calls exit.  Calls abort.
> Solaris 2.3:   Calls two.   Calls one.   Terminates normally. Exit val 1.
> Redhat 4.1/x86: Calls two.   Calls one.  Calls two.  Call two.  Repeats
> 	until stack size hits 8Mb ulimit.  Faults.
> 

I got the same result as Linux on Windows NT 4.0 with VC++ 5.0.
However I can change Linux to whatever behaviorw which makes
more senses.

How about call everyone on the list and use the status in the
last exit () call? BTW, it seems to be what happens on Solaris.

> 
> If we decide that calling exit() from a destructor really is a 
> questionable idea, we can just change the test case to call _exit()
> instead of exit() in the destructor and we can put HAVE_ATEXIT back
> in sco5.h.  
> 
> Now exactly how this ties into the Unixware stuff at this point,
> I'm unsure...
> 
> 
> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> void one(void)
> {
>         printf("One\n");
>         exit(1);
> }
> 
> void two(void)
> {
>         printf("two\n");
> }
> 
> 
> int main(void)
> {
>         atexit(one);
>         atexit(two);
>         exit(1);
> }
> 
> 


-- 
H.J. Lu (hjl@gnu.ai.mit.edu)

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

end of thread, other threads:[~1997-11-10 14:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-11-07  9:25 egcs 10-31 and UnixWare acs
1997-11-09 10:14 ` Jeffrey A Law
1997-11-09 11:16   ` Robert Lipe
1997-11-09 13:49     ` Jeffrey A Law
1997-11-09 12:35       ` acs
1997-11-09 13:00       ` Robert Lipe
1997-11-09 17:00         ` Jeffrey A Law
1997-11-09 18:35           ` Joe Buck
1997-11-09 21:08             ` Joern Rennecke
1997-11-09 20:32           ` Robert Lipe
1997-11-10 14:57             ` H.J. Lu
1997-11-10 14:57               ` Robert Lipe
1997-11-10 12:27                 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).