diff --git a/ChangeLog b/ChangeLog index e67fbaf9bc..0384c4cab0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,16 @@ 2005-09-27 Ulrich Drepper + [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 +#include +#include + +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 +#include +#include + +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 +#include + +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 +#include +#include +#include + +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"