diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2014-11-23 08:46:50 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2014-11-23 08:46:50 +0000 |
commit | b54cb287e993d980f2843319469c0c1098cc650c (patch) | |
tree | a48ddb3b95505a0022e6ad52adf4df3e23bc7829 /regress/lib | |
parent | 45bbbcf6bcfa9344c3f4a557b961113ee0128916 (diff) |
Add regress for atexit() vs DSO unloading and start on a similar test
for pthread_atfork()
Diffstat (limited to 'regress/lib')
-rw-r--r-- | regress/lib/csu/Makefile | 6 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/Makefile | 8 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/atexit/Makefile | 39 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/atexit/atexit_test.c | 119 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/atexit/expected.out | 30 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/libaa/Makefile | 11 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/libaa/aa.c | 49 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/libaa/shlib_version | 2 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/libab/Makefile | 11 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/libab/ab.c | 49 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/libab/shlib_version | 2 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/pthread_atfork/Makefile | 49 | ||||
-rw-r--r-- | regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c | 154 |
13 files changed, 528 insertions, 1 deletions
diff --git a/regress/lib/csu/Makefile b/regress/lib/csu/Makefile index 53396e481b7..ac2ae3ae23e 100644 --- a/regress/lib/csu/Makefile +++ b/regress/lib/csu/Makefile @@ -1,7 +1,11 @@ -# $OpenBSD: Makefile,v 1.4 2012/09/08 20:09:49 matthew Exp $ +# $OpenBSD: Makefile,v 1.5 2014/11/23 08:46:49 guenther Exp $ SUBDIR+= ctors dtors init_priority +.if !defined(NOPIC) +SUBDIR+= callbacks +.endif + install: .include <bsd.subdir.mk> diff --git a/regress/lib/csu/callbacks/Makefile b/regress/lib/csu/callbacks/Makefile new file mode 100644 index 00000000000..48474134a56 --- /dev/null +++ b/regress/lib/csu/callbacks/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ + +SUBDIR+= libaa libab atexit +# not yet: pthread_atfork + +install: + +.include <bsd.subdir.mk> diff --git a/regress/lib/csu/callbacks/atexit/Makefile b/regress/lib/csu/callbacks/atexit/Makefile new file mode 100644 index 00000000000..1d90d336410 --- /dev/null +++ b/regress/lib/csu/callbacks/atexit/Makefile @@ -0,0 +1,39 @@ +# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ + +.include <bsd.obj.mk> + +AA_DIR=${.CURDIR}/../libaa +AA_OBJDIR!= if [ -d $(AA_DIR)/${__objdir} ]; then \ + echo "$(AA_DIR)/${__objdir}"; \ + else \ + echo "$(AA_DIR)"; \ + fi + +AB_DIR=${.CURDIR}/../libab +AB_OBJDIR!= if [ -d $(AB_DIR)/${__objdir} ]; then \ + echo "$(AB_DIR)/${__objdir}"; \ + else \ + echo "$(AB_DIR)"; \ + fi + +PROG= atexit_test + +SRCS= atexit_test.c + +CFLAGS+= -DLIBAA="\"$(AA_OBJDIR)/libaa.so\"" +CFLAGS+= -DLIBAB="\"$(AB_OBJDIR)/libab.so\"" +LDFLAGS+= -Wl,-E + +NOMAN= + +regress-atexit: ${PROG} + for i in 0 1 2 3; do \ + ./${PROG} $$i || exit; \ + printf "finished $$i\n\n"; \ + done | cmp -s - ${.CURDIR}/expected.out + +REGRESS_TARGETS=regress-atexit + +install: + +.include <bsd.regress.mk> diff --git a/regress/lib/csu/callbacks/atexit/atexit_test.c b/regress/lib/csu/callbacks/atexit/atexit_test.c new file mode 100644 index 00000000000..3db198c6e70 --- /dev/null +++ b/regress/lib/csu/callbacks/atexit/atexit_test.c @@ -0,0 +1,119 @@ +/* $OpenBSD: atexit_test.c,v 1.1 2014/11/23 08:46:49 guenther Exp $ */ + +/* + * Copyright (c) 2014 Philip Guenther <guenther@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <dlfcn.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> + +void *libaa, *libab; + +#define CALLBACK(name) static void name(void) { printf("exe "#name"\n"); } + +CALLBACK(cleanup1) +CALLBACK(cleanup2) +CALLBACK(cleanup3) + +static void +cleanup_dlclose(void) +{ + printf("exe cleanup_dlclose begin\n"); + dlclose(libaa); + dlclose(libab); + printf("exe cleanup_dlclose end\n"); +} + +static void +aa(void) +{ + void (*func)(void) = dlsym(libaa, "aa"); + if (func == NULL) + errx(1, "dlsym(libaa, aa): %s", dlerror()); + func(); +} + +static void +ab(void) +{ + void (*func)(void) = dlsym(libab, "ab"); + if (func == NULL) + errx(1, "dlsym(libab, ab): %s", dlerror()); + func(); +} + +int +main(int argc, char **argv) +{ + int test; + + libaa = dlopen(LIBAA, RTLD_LAZY); + if (libaa == NULL) + errx(1, "dlopen(%s, RTLD_LAZY): %s", LIBAA, dlerror()); + + libab = dlopen(LIBAB, RTLD_LAZY); + if (libab == NULL) + errx(1, "dlopen(%s, RTLD_LAZY): %s", LIBAB, dlerror()); + + if (argc != 2) + test = 0; + else + test = atoi(argv[1]); + + switch (test) { + case 0: + /* 1, aa, 2, ab, 3, then exit */ + atexit(cleanup1); + aa(); + atexit(cleanup2); + ab(); + atexit(cleanup3); + exit(0); + + case 1: + /* 1, aa, 2, ab, 3, then dlclose aa, then bb */ + atexit(cleanup1); + aa(); + atexit(cleanup2); + ab(); + atexit(cleanup3); + dlclose(libaa); + dlclose(libab); + exit(0); + + case 2: + /* 1, aa, cleanup_dlclose, ab, 3, then exit */ + atexit(cleanup1); + aa(); + atexit(cleanup_dlclose); + ab(); + atexit(cleanup3); + exit(0); + + case 3: + /* 1, aa, 2, ab, cleanup_dlclose, then exit */ + atexit(cleanup1); + aa(); + atexit(cleanup2); + ab(); + atexit(cleanup_dlclose); + exit(0); + + } + + return (0); +} diff --git a/regress/lib/csu/callbacks/atexit/expected.out b/regress/lib/csu/callbacks/atexit/expected.out new file mode 100644 index 00000000000..d2cff7fbfac --- /dev/null +++ b/regress/lib/csu/callbacks/atexit/expected.out @@ -0,0 +1,30 @@ +exe cleanup3 +libab cleanup +exe cleanup2 +libaa cleanup +exe cleanup1 +finished 0 + +libaa cleanup +libab cleanup +exe cleanup3 +exe cleanup2 +exe cleanup1 +finished 1 + +exe cleanup3 +libab cleanup +exe cleanup_dlclose begin +libaa cleanup +exe cleanup_dlclose end +exe cleanup1 +finished 2 + +exe cleanup_dlclose begin +libaa cleanup +libab cleanup +exe cleanup_dlclose end +exe cleanup2 +exe cleanup1 +finished 3 + diff --git a/regress/lib/csu/callbacks/libaa/Makefile b/regress/lib/csu/callbacks/libaa/Makefile new file mode 100644 index 00000000000..4153c05ff1b --- /dev/null +++ b/regress/lib/csu/callbacks/libaa/Makefile @@ -0,0 +1,11 @@ +# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ + +LIB=aa +SRCS= aa.c +NOPROFILE=yes + +regress: all + +install: + +.include <bsd.lib.mk> diff --git a/regress/lib/csu/callbacks/libaa/aa.c b/regress/lib/csu/callbacks/libaa/aa.c new file mode 100644 index 00000000000..5a84e92cc0b --- /dev/null +++ b/regress/lib/csu/callbacks/libaa/aa.c @@ -0,0 +1,49 @@ +/* $OpenBSD: aa.c,v 1.1 2014/11/23 08:46:49 guenther Exp $ */ + +/* + * Copyright (c) 2014 Philip Guenther <guenther@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> + +#define CALLBACK(file, name) \ + static void name(void) \ + { \ + fprintf(file, "libaa "#name"\n"); \ + fflush(file); \ + } + +CALLBACK(stdout, cleanup) + +void +aa(void) +{ + atexit(cleanup); +} + +static FILE *otherf; + +CALLBACK(stdout, atfork_prepare) +CALLBACK(stdout, atfork_parent) +CALLBACK(otherf, atfork_child) + +void +aa_atfork(FILE *f) +{ + otherf = f; + pthread_atfork(atfork_prepare, atfork_parent, atfork_child); +} diff --git a/regress/lib/csu/callbacks/libaa/shlib_version b/regress/lib/csu/callbacks/libaa/shlib_version new file mode 100644 index 00000000000..97c9f92d6b8 --- /dev/null +++ b/regress/lib/csu/callbacks/libaa/shlib_version @@ -0,0 +1,2 @@ +major=0 +minor=0 diff --git a/regress/lib/csu/callbacks/libab/Makefile b/regress/lib/csu/callbacks/libab/Makefile new file mode 100644 index 00000000000..df6be6ada7e --- /dev/null +++ b/regress/lib/csu/callbacks/libab/Makefile @@ -0,0 +1,11 @@ +# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ + +LIB=ab +SRCS= ab.c +NOPROFILE=yes + +regress: all + +install: + +.include <bsd.lib.mk> diff --git a/regress/lib/csu/callbacks/libab/ab.c b/regress/lib/csu/callbacks/libab/ab.c new file mode 100644 index 00000000000..fcf6b79213e --- /dev/null +++ b/regress/lib/csu/callbacks/libab/ab.c @@ -0,0 +1,49 @@ +/* $OpenBSD: ab.c,v 1.1 2014/11/23 08:46:49 guenther Exp $ */ + +/* + * Copyright (c) 2014 Philip Guenther <guenther@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> + +#define CALLBACK(file, name) \ + static void name(void) \ + { \ + fprintf(file, "libab "#name"\n"); \ + fflush(file); \ + } + +CALLBACK(stdout, cleanup) + +void +ab(void) +{ + atexit(cleanup); +} + +static FILE *otherf; + +CALLBACK(stdout, atfork_prepare) +CALLBACK(stdout, atfork_parent) +CALLBACK(otherf, atfork_child) + +void +ab_atfork(FILE *f) +{ + otherf = f; + pthread_atfork(atfork_prepare, atfork_parent, atfork_child); +} diff --git a/regress/lib/csu/callbacks/libab/shlib_version b/regress/lib/csu/callbacks/libab/shlib_version new file mode 100644 index 00000000000..97c9f92d6b8 --- /dev/null +++ b/regress/lib/csu/callbacks/libab/shlib_version @@ -0,0 +1,2 @@ +major=0 +minor=0 diff --git a/regress/lib/csu/callbacks/pthread_atfork/Makefile b/regress/lib/csu/callbacks/pthread_atfork/Makefile new file mode 100644 index 00000000000..8e685447d7b --- /dev/null +++ b/regress/lib/csu/callbacks/pthread_atfork/Makefile @@ -0,0 +1,49 @@ +# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ + +.include <bsd.obj.mk> + +AA_DIR=${.CURDIR}/../libaa +AA_OBJDIR!= if [ -d $(AA_DIR)/${__objdir} ]; then \ + echo "$(AA_DIR)/${__objdir}"; \ + else \ + echo "$(AA_DIR)"; \ + fi + +AB_DIR=${.CURDIR}/../libab +AB_OBJDIR!= if [ -d $(AB_DIR)/${__objdir} ]; then \ + echo "$(AB_DIR)/${__objdir}"; \ + else \ + echo "$(AB_DIR)"; \ + fi + +PROG= pthread_atfork_test + +SRCS= pthread_atfork_test.c + +CFLAGS+= -DLIBAA="\"$(AA_OBJDIR)/libaa.so\"" +CFLAGS+= -DLIBAB="\"$(AB_OBJDIR)/libab.so\"" +LDFLAGS+= -Wl,-E + +LDADD+= -lpthread +DPADD+= ${LIBPTHREAD} + +NOMAN= + +CLEANFILES= parent_out child_out + +TESTS= 0 + +regress-pthread_atfork: ${PROG} + for i in ${TESTS}; do \ + ./${PROG} $$i || exit; \ + printf "finished $$i\n\n"; \ + printf "finished $$i\n\n" >&3; \ + done >parent_out 3>child_out + cmp -s parent_out ${.CURDIR}/expected_parent.out + cmp -s child_out ${.CURDIR}/expected_child.out + +REGRESS_TARGETS=regress-pthread_atfork + +install: + +.include <bsd.regress.mk> diff --git a/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c b/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c new file mode 100644 index 00000000000..c6a93a0e080 --- /dev/null +++ b/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c @@ -0,0 +1,154 @@ +/* $OpenBSD: pthread_atfork_test.c,v 1.1 2014/11/23 08:46:49 guenther Exp $ */ + +/* + * Copyright (c) 2014 Philip Guenther <guenther@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <dlfcn.h> +#include <err.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +void *libaa, *libab; + +FILE *otherf; + +#define CALLBACK(file, name) \ + static void name(void) \ + { \ + fprintf(file, "testp "#name"\n"); \ + fflush(file); \ + } + +#define ATFORK_CALLBACKS(name) \ + CALLBACK(stdout, name##_prepare) \ + CALLBACK(stdout, name##_parent) \ + CALLBACK(otherf, name##_child) + +ATFORK_CALLBACKS(atfork1) +ATFORK_CALLBACKS(atfork2) +ATFORK_CALLBACKS(atfork3) + +static void +atfork_dlclose(void) +{ + printf("exe atfork_dlclose begin\n"); + dlclose(libaa); + dlclose(libab); + printf("exe atfork_dlclose end\n"); + fflush(stdout); +} + +static void +aa_atfork(void) +{ + void (*func)(FILE *) = dlsym(libaa, "aa_atfork"); + if (func == NULL) + errx(1, "dlsym(libaa, aa_atfork): %s", dlerror()); + func(otherf); +} + +static void +ab_atfork(void) +{ + void (*func)(FILE *) = dlsym(libab, "ab_atfork"); + if (func == NULL) + errx(1, "dlsym(libab, ab_atfork): %s", dlerror()); + func(otherf); +} + +#define REGISTER(prep, parent, child) \ + do { \ + int _r = pthread_atfork(prep, parent, child); \ + if (_r) \ + errc(1, _r, "pthread_atfork(%s,%s,%s)", \ + #prep, #parent, #child); \ + } while (0) + +#define REGISTER_ALL(name) \ + REGISTER(name##_prepare, name##_parent, name##_child) + +int +main(int argc, char **argv) +{ + pid_t pid; + int test; + + otherf = fdopen(3, "w"); + if (otherf == NULL) + otherf = stderr; + + libaa = dlopen(LIBAA, RTLD_LAZY); + if (libaa == NULL) + errx(1, "dlopen(%s, RTLD_LAZY): %s", LIBAA, dlerror()); + + libab = dlopen(LIBAB, RTLD_LAZY); + if (libab == NULL) + errx(1, "dlopen(%s, RTLD_LAZY): %s", LIBAB, dlerror()); + + if (argc != 2) + test = 0; + else + test = atoi(argv[1]); + + switch (test) { + case 0: + /* 1, aa, 2, ab, 3, then fork */ + REGISTER_ALL(atfork1); + aa_atfork(); + REGISTER_ALL(atfork2); + ab_atfork(); + REGISTER_ALL(atfork3); + break; + + case 1: + /* 1, aa, 2, ab, 3, then dlclose aa and bb, then fork */ + REGISTER_ALL(atfork1); + aa_atfork(); + REGISTER_ALL(atfork2); + ab_atfork(); + REGISTER_ALL(atfork3); + dlclose(libaa); + dlclose(libab); + break; + + case 2: + /* 1, aa, atfork_dlclose, ab, 3, then fork */ + REGISTER_ALL(atfork1); + aa_atfork(); + REGISTER(atfork_dlclose, NULL, NULL); + ab_atfork(); + REGISTER_ALL(atfork3); + break; + + case 3: + /* 1, aa, 2, ab, atfork_dlclose, then fork */ + REGISTER_ALL(atfork1); + aa_atfork(); + REGISTER_ALL(atfork2); + ab_atfork(); + REGISTER(atfork_dlclose, NULL, NULL); + break; + + } + + fflush(stdout); + fflush(otherf); + pid = fork(); + + return (0); +} |