about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--dlfcn/Makefile19
-rw-r--r--dlfcn/bug-atexit1-lib.c375
-rw-r--r--dlfcn/bug-atexit1.c23
-rw-r--r--dlfcn/bug-atexit2-lib.c14
-rw-r--r--dlfcn/bug-atexit2.c53
6 files changed, 490 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index e67fbaf9bc..0384c4cab0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,16 @@
 
 2005-09-27  Ulrich Drepper  <drepper@redhat.com>
 
+	[BZ #1158]
+	* stdlib/cxa_atexit.c (__new_exitfn): Rewrite to preserve order in
+	which the functions were registered.
+	* dlfcn/Makefile: Add rules to build and run bug-atexit1 and
+	bug-atexit2.
+	* dlfcn/bug-atext1.c: New file.
+	* dlfcn/bug-atext1-lib.c: New file.
+	* dlfcn/bug-atext2.c: New file.
+	* dlfcn/bug-atext2-lib.c: New file.
+
 	[BZ #1078]
 	* libio/fileops.c (_IO_new_file_xsputn): Determine amount of
 	available space in non-line-buffered buffer correctly.
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
index 7b538fed2b..3f1a8fa6ae 100644
--- a/dlfcn/Makefile
+++ b/dlfcn/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -26,7 +26,8 @@ elide-routines.os := $(routines)
 distribute	:= dlopenold.c glreflib1.c glreflib2.c failtestmod.c \
 		   defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \
 		   modcxaatexit.c modstatic.c modstatic2.c \
-		   bug-dlsym1-lib1.c bug-dlsym1-lib2.c
+		   bug-dlsym1-lib1.c bug-dlsym1-lib2.c bug-atexit1-lib.c \
+		   bug-atexit2-lib.c
 
 extra-libs-others := libdl
 
@@ -39,14 +40,15 @@ endif
 
 ifeq (yes,$(build-shared))
 tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
-	bug-dlopen1 bug-dlsym1 tst-dlinfo
+	bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2
 ifeq (yes,$(have-protected))
 tests += tstatexit
 endif
 endif
 modules-names = glreflib1 glreflib2 failtestmod defaultmod1 defaultmod2 \
 		errmsg1mod modatexit modcxaatexit \
-		bug-dlsym1-lib1 bug-dlsym1-lib2
+		bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
+		bug-atexit2-lib
 
 failtestmod.so-no-z-defs = yes
 glreflib2.so-no-z-defs = yes
@@ -125,6 +127,15 @@ $(objpfx)bug-dlsym1-lib1.so: $(objpfx)bug-dlsym1-lib2.so \
 $(objpfx)bug-dlsym1-lib2.so: $(common-objpfx)libc.so \
 			     $(common-objpfx)libc_nonshared.a
 
+$(objpfx)bug-atexit1: $(libdl)
+$(objpfx)bug-atexit1.out: $(objpfx)bug-atexit1-lib.so
+$(objpfx)bug-atexit1-lib.so: $(common-objpfx)libc.so \
+			     $(common-objpfx)libc_nonshared.a
+
+$(objpfx)bug-atexit2: $(libdl)
+$(objpfx)bug-atexit2.out: $(objpfx)bug-atexit2-lib.so
+$(objpfx)bug-atexit2-lib.so: $(common-objpfx)libc.so \
+			     $(common-objpfx)libc_nonshared.a
 
 
 # Depend on libc.so so a DT_NEEDED is generated in the shared objects.
diff --git a/dlfcn/bug-atexit1-lib.c b/dlfcn/bug-atexit1-lib.c
new file mode 100644
index 0000000000..715bb40b23
--- /dev/null
+++ b/dlfcn/bug-atexit1-lib.c
@@ -0,0 +1,375 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int next;
+
+void
+f00 (void)
+{
+  puts ("f00");
+  if (next-- != 0)
+    _exit (1);
+}
+
+void
+f01 (void)
+{
+  puts ("f01");
+  if (next-- != 1)
+    _exit (1);
+}
+
+void
+f02 (void)
+{
+  puts ("f02");
+  if (next-- != 2)
+    _exit (1);
+}
+
+void
+f03 (void)
+{
+  puts ("f03");
+  if (next-- != 3)
+    _exit (1);
+}
+
+void
+f04 (void)
+{
+  puts ("f04");
+  if (next-- != 4)
+    _exit (1);
+}
+
+void
+f05 (void)
+{
+  puts ("f05");
+  if (next-- != 5)
+    _exit (1);
+}
+
+void
+f06 (void)
+{
+  puts ("f06");
+  if (next-- != 6)
+    _exit (1);
+}
+
+void
+f07 (void)
+{
+  puts ("f07");
+  if (next-- != 7)
+    _exit (1);
+}
+
+void
+f08 (void)
+{
+  puts ("f08");
+  if (next-- != 8)
+    _exit (1);
+}
+
+void
+f09 (void)
+{
+  puts ("f09");
+  if (next-- != 9)
+    _exit (1);
+}
+
+void
+f10 (void)
+{
+  puts ("f10");
+  if (next-- != 10)
+    _exit (1);
+}
+
+void
+f11 (void)
+{
+  puts ("f11");
+  if (next-- != 11)
+    _exit (1);
+}
+
+void
+f12 (void)
+{
+  puts ("f12");
+  if (next-- != 12)
+    _exit (1);
+}
+
+void
+f13 (void)
+{
+  puts ("f13");
+  if (next-- != 13)
+    _exit (1);
+}
+
+void
+f14 (void)
+{
+  puts ("f14");
+  if (next-- != 14)
+    _exit (1);
+}
+
+void
+f15 (void)
+{
+  puts ("f15");
+  if (next-- != 15)
+    _exit (1);
+}
+
+void
+f16 (void)
+{
+  puts ("f16");
+  if (next-- != 16)
+    _exit (1);
+}
+
+void
+f17 (void)
+{
+  puts ("f17");
+  if (next-- != 17)
+    _exit (1);
+}
+
+void
+f18 (void)
+{
+  puts ("f18");
+  if (next-- != 18)
+    _exit (1);
+}
+
+void
+f19 (void)
+{
+  puts ("f19");
+  if (next-- != 19)
+    _exit (1);
+}
+
+void
+f20 (void)
+{
+  puts ("f20");
+  if (next-- != 20)
+    _exit (1);
+}
+
+void
+f21 (void)
+{
+  puts ("f21");
+  if (next-- != 21)
+    _exit (1);
+}
+
+void
+f22 (void)
+{
+  puts ("f22");
+  if (next-- != 22)
+    _exit (1);
+}
+
+void
+f23 (void)
+{
+  puts ("f23");
+  if (next-- != 23)
+    _exit (1);
+}
+
+void
+f24 (void)
+{
+  puts ("f24");
+  if (next-- != 24)
+    _exit (1);
+}
+
+void
+f25 (void)
+{
+  puts ("f25");
+  if (next-- != 25)
+    _exit (1);
+}
+
+void
+f26 (void)
+{
+  puts ("f26");
+  if (next-- != 26)
+    _exit (1);
+}
+
+void
+f27 (void)
+{
+  puts ("f27");
+  if (next-- != 27)
+    _exit (1);
+}
+
+void
+f28 (void)
+{
+  puts ("f28");
+  if (next-- != 28)
+    _exit (1);
+}
+
+void
+f29 (void)
+{
+  puts ("f29");
+  if (next-- != 29)
+    _exit (1);
+}
+
+void
+f30 (void)
+{
+  puts ("f30");
+  if (next-- != 30)
+    _exit (1);
+}
+
+void
+f31 (void)
+{
+  puts ("f31");
+  if (next-- != 31)
+    _exit (1);
+}
+
+void
+f32 (void)
+{
+  puts ("f32");
+  if (next-- != 32)
+    _exit (1);
+}
+
+void
+f33 (void)
+{
+  puts ("f33");
+  if (next-- != 33)
+    _exit (1);
+}
+
+void
+f34 (void)
+{
+  puts ("f34");
+  if (next-- != 34)
+    _exit (1);
+}
+
+void
+f35 (void)
+{
+  puts ("f35");
+  if (next-- != 35)
+    _exit (1);
+}
+
+void
+f36 (void)
+{
+  puts ("f36");
+  if (next-- != 36)
+    _exit (1);
+}
+
+void
+f37 (void)
+{
+  puts ("f37");
+  if (next-- != 37)
+    _exit (1);
+}
+
+void
+f38 (void)
+{
+  puts ("f38");
+  if (next-- != 38)
+    _exit (1);
+}
+
+void
+f39 (void)
+{
+  puts ("f39");
+  if (next-- != 39)
+    _exit (1);
+}
+
+void
+foo (void)
+{
+  atexit (f00);
+  atexit (f01);
+  atexit (f02);
+  atexit (f03);
+  atexit (f04);
+  atexit (f05);
+  atexit (f06);
+  atexit (f07);
+  atexit (f08);
+  atexit (f09);
+
+  atexit (f10);
+  atexit (f11);
+  atexit (f12);
+  atexit (f13);
+  atexit (f14);
+  atexit (f15);
+  atexit (f16);
+  atexit (f17);
+  atexit (f18);
+  atexit (f19);
+
+  atexit (f20);
+  atexit (f21);
+  atexit (f22);
+  atexit (f23);
+  atexit (f24);
+  atexit (f25);
+  atexit (f26);
+  atexit (f27);
+  atexit (f28);
+  atexit (f29);
+
+  atexit (f30);
+  atexit (f31);
+  atexit (f32);
+  atexit (f33);
+  atexit (f34);
+  atexit (f35);
+  atexit (f36);
+  atexit (f37);
+  atexit (f38);
+  atexit (f39);
+
+  next = 39;
+}
diff --git a/dlfcn/bug-atexit1.c b/dlfcn/bug-atexit1.c
new file mode 100644
index 0000000000..3bdb5587b1
--- /dev/null
+++ b/dlfcn/bug-atexit1.c
@@ -0,0 +1,23 @@
+/* Derived from a test case in
+   http://sourceware.org/bugzilla/show_bug.cgi?id=1158.  */
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+  for (int i = 0; i < 2; ++i)
+    {
+      void *dso = dlopen ("$ORIGIN/bug-atexit1-lib.so", RTLD_NOW);
+      void (*fn) (void) = (void (*)()) dlsym (dso, "foo");
+      fn ();
+      dlclose (dso);
+      puts ("round done");
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/dlfcn/bug-atexit2-lib.c b/dlfcn/bug-atexit2-lib.c
new file mode 100644
index 0000000000..ca39657566
--- /dev/null
+++ b/dlfcn/bug-atexit2-lib.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+fx (void)
+{
+  puts ("At exit fx");
+}
+
+void
+foo (void)
+{
+  atexit (fx);
+}
diff --git a/dlfcn/bug-atexit2.c b/dlfcn/bug-atexit2.c
new file mode 100644
index 0000000000..15e9f7aa01
--- /dev/null
+++ b/dlfcn/bug-atexit2.c
@@ -0,0 +1,53 @@
+/* Derived from a test case in
+   http://sourceware.org/bugzilla/show_bug.cgi?id=1158.  */
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int next = 3;
+
+static void
+f1 (void)
+{
+  puts ("f1");
+  if (next-- != 1)
+    _exit (1);
+}
+
+static void
+f2 (void)
+{
+  puts ("f2");
+  if (next-- != 2)
+    _exit (1);
+}
+
+static void
+f3 (void)
+{
+  puts ("f3");
+  if (next-- != 3)
+    _exit (1);
+}
+
+static int
+do_test (void)
+{
+  atexit (f1);
+
+  void *dso = dlopen ("$ORIGIN/bug-atexit2-lib.so", RTLD_NOW);
+  void (*fn) (void) = (void (*) (void)) dlsym (dso, "foo");
+  fn ();
+
+  atexit (f2);
+
+  dlclose (dso);
+
+  atexit (f3);
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"