From 314a431d37757ad179e89b83c3cb5720bae26e60 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 7 Jun 2020 23:32:58 +0000 Subject: htl: Enable more tests * nptl/tst-_res1.c, tst-_res1mod1.c, tst-_res1mod2.c, tst-atfork2.c, tst-atfork2mod.c, tst-fini1.c, tst-fini1mod.c, tst-tls4.c, tst-tls4moda.c, tst-tls4modb.c: Move to... * sysdeps/pthread: ... here. Rename tst-tls4.c to tst-pt-tls4.c to avoid conflicting with elf/tst-tls4.c. * nptl/Makefile: Move corresponding references and rules to... * sysdeps/pthread/Makefile: ... here. --- nptl/Makefile | 41 +-------- nptl/tst-_res1.c | 68 --------------- nptl/tst-_res1mod1.c | 22 ----- nptl/tst-_res1mod2.c | 1 - nptl/tst-atfork2.c | 158 ---------------------------------- nptl/tst-atfork2mod.c | 57 ------------- nptl/tst-fini1.c | 34 -------- nptl/tst-fini1mod.c | 71 --------------- nptl/tst-tls4.c | 180 --------------------------------------- nptl/tst-tls4moda.c | 49 ----------- nptl/tst-tls4modb.c | 58 ------------- sysdeps/pthread/Makefile | 41 +++++++++ sysdeps/pthread/tst-_res1.c | 68 +++++++++++++++ sysdeps/pthread/tst-_res1mod1.c | 22 +++++ sysdeps/pthread/tst-_res1mod2.c | 1 + sysdeps/pthread/tst-atfork2.c | 158 ++++++++++++++++++++++++++++++++++ sysdeps/pthread/tst-atfork2mod.c | 57 +++++++++++++ sysdeps/pthread/tst-fini1.c | 34 ++++++++ sysdeps/pthread/tst-fini1mod.c | 71 +++++++++++++++ sysdeps/pthread/tst-pt-tls4.c | 180 +++++++++++++++++++++++++++++++++++++++ sysdeps/pthread/tst-tls4moda.c | 49 +++++++++++ sysdeps/pthread/tst-tls4modb.c | 58 +++++++++++++ 22 files changed, 743 insertions(+), 735 deletions(-) delete mode 100644 nptl/tst-_res1.c delete mode 100644 nptl/tst-_res1mod1.c delete mode 100644 nptl/tst-_res1mod2.c delete mode 100644 nptl/tst-atfork2.c delete mode 100644 nptl/tst-atfork2mod.c delete mode 100644 nptl/tst-fini1.c delete mode 100644 nptl/tst-fini1mod.c delete mode 100644 nptl/tst-tls4.c delete mode 100644 nptl/tst-tls4moda.c delete mode 100644 nptl/tst-tls4modb.c create mode 100644 sysdeps/pthread/tst-_res1.c create mode 100644 sysdeps/pthread/tst-_res1mod1.c create mode 100644 sysdeps/pthread/tst-_res1mod2.c create mode 100644 sysdeps/pthread/tst-atfork2.c create mode 100644 sysdeps/pthread/tst-atfork2mod.c create mode 100644 sysdeps/pthread/tst-fini1.c create mode 100644 sysdeps/pthread/tst-fini1mod.c create mode 100644 sysdeps/pthread/tst-pt-tls4.c create mode 100644 sysdeps/pthread/tst-tls4moda.c create mode 100644 sysdeps/pthread/tst-tls4modb.c diff --git a/nptl/Makefile b/nptl/Makefile index 9b549454f1..3f0b107d2f 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -364,27 +364,23 @@ tests += tst-cancelx4 tst-cancelx5 tst-cancelx6 tst-cancelx7 tst-cancelx9 \ tst-cleanupx4 ifeq ($(build-shared),yes) -tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \ - tst-audit-threads +tests += tst-compat-forwarder tst-audit-threads tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1 -tests-nolibpthread += tst-fini1 ifeq ($(have-z-execstack),yes) tests += tst-execstack endif endif -modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ +modules-names = tst-tls3mod \ tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ - tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \ + tst-execstack-mod \ tst-compat-forwarder-mod tst-audit-threads-mod1 \ tst-audit-threads-mod2 extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \ tst-cleanup4aux.o tst-cleanupx4aux.o test-extras += tst-cleanup4aux tst-cleanupx4aux -test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names))) -tst-atfork2mod.so-no-z-defs = yes tst-tls3mod.so-no-z-defs = yes tst-tls5mod.so-no-z-defs = yes tst-tls5moda.so-no-z-defs = yes @@ -394,11 +390,6 @@ tst-tls5modd.so-no-z-defs = yes tst-tls5mode.so-no-z-defs = yes tst-tls5modf.so-no-z-defs = yes -ifeq ($(build-shared),yes) -# Build all the modules even when not actually running test programs. -tests: $(test-modules) -endif - ifeq ($(build-shared),yes) # Set the `multidir' variable by grabbing the variable from the compiler. @@ -510,11 +501,6 @@ CFLAGS-tst-initializers1-gnu11.c += $(CFLAGS-tst-initializers1-<) tst-cancel7-ARGS = --command "exec $(host-test-program-cmd)" tst-cancelx7-ARGS = $(tst-cancel7-ARGS) -$(objpfx)tst-atfork2: $(libdl) $(shared-thread-library) -LDFLAGS-tst-atfork2 = -rdynamic -tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace -$(objpfx)tst-atfork2mod.so: $(shared-thread-library) - tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace $(objpfx)tst-stack3-mem.out: $(objpfx)tst-stack3.out $(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@; \ @@ -546,9 +532,6 @@ $(objpfx)tst-tls3-malloc: $(libdl) $(shared-thread-library) LDFLAGS-tst-tls3-malloc = -rdynamic $(objpfx)tst-tls3-malloc.out: $(objpfx)tst-tls3mod.so -$(objpfx)tst-tls4: $(libdl) $(shared-thread-library) -$(objpfx)tst-tls4.out: $(objpfx)tst-tls4moda.so $(objpfx)tst-tls4modb.so - $(objpfx)tst-tls5: $(objpfx)tst-tls5mod.so $(shared-thread-library) LDFLAGS-tst-tls5 = -Wl,--no-as-needed LDFLAGS-tst-tls5mod.so = -Wl,-soname,tst-tls5mod.so @@ -565,8 +548,6 @@ endif $(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library) -$(objpfx)tst-fini1: $(shared-thread-library) $(objpfx)tst-fini1mod.so - ifeq (yes,$(build-shared)) librt = $(common-objpfx)rt/librt.so else @@ -579,11 +560,6 @@ $(common-objpfx)rt/librt.so: $(shared-thread-library) $(objpfx)tst-cancel17: $(librt) $(objpfx)tst-cancelx17: $(librt) -$(objpfx)tst-_res1mod2.so: $(objpfx)tst-_res1mod1.so -LDFLAGS-tst-_res1mod1.so = -Wl,-soname,tst-_res1mod1.so -LDFLAGS-tst-_res1mod2.so = -Wl,-soname,tst-_res1mod2.so -$(objpfx)tst-_res1: $(objpfx)tst-_res1mod1.so $(objpfx)tst-_res1mod2.so \ - $(shared-thread-library) LDLIBS-tst-cancel24 = -Wl,--no-as-needed -lstdc++ LDLIBS-tst-cancel24-static = $(LDLIBS-tst-cancel24) @@ -593,10 +569,6 @@ $(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs)) $(objpfx)libpthread.so: +preinit += $(addprefix $(objpfx),$(crti-objs)) $(objpfx)libpthread.so: +postinit += $(addprefix $(objpfx),$(crtn-objs)) -ifeq ($(build-shared),yes) -$(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so -endif - ifeq ($(build-shared),yes) $(objpfx)crti.o: $(objpfx)pt-crti.o ln -f $< $@ @@ -609,10 +581,7 @@ $(objpfx)$(multidir)/crtn.o: $(objpfx)crtn.o $(objpfx)$(multidir)/ ln -f $< $@ endif -generated += multidir.mk tst-atfork2.mtrace tst-tls6.out - -generated += $(objpfx)tst-atfork2.mtrace \ - $(addsuffix .so,$(strip $(modules-names))) +generated += multidir.mk tst-tls6.out # Give libpthread.so an entry point and make it directly runnable itself. LDFLAGS-pthread.so += -e __nptl_main @@ -627,8 +596,6 @@ $(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so LDFLAGS-tst-execstack = -Wl,-z,noexecstack CFLAGS-tst-execstack-mod.c += -Wno-trampolines -$(objpfx)tst-fini1mod.so: $(shared-thread-library) - tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child" tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" diff --git a/nptl/tst-_res1.c b/nptl/tst-_res1.c deleted file mode 100644 index 3e186bcb39..0000000000 --- a/nptl/tst-_res1.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* Test whether _res in glibc 2.1.x and earlier (before __res_state() - was introduced) works. Portable programs should never do the - dirty things below. */ - -#include -#include -#include -#include - -void *tf (void *resp) -{ - if (resp == &_res || resp == __res_state ()) - abort (); - _res.retry = 24; - return NULL; -} - -void do_test (struct __res_state *resp) -{ - if (resp != &_res || resp != __res_state ()) - abort (); - if (_res.retry != 12) - abort (); -} - -int main (void) -{ -#undef _res - extern struct __res_state _res; - pthread_t th; - - _res.retry = 12; - if (pthread_create (&th, NULL, tf, &_res) != 0) - { - puts ("create failed"); - exit (1); - } - - do_test (&_res); - - if (pthread_join (th, NULL) != 0) - { - puts ("join failed"); - exit (1); - } - - do_test (&_res); - - exit (0); -} diff --git a/nptl/tst-_res1mod1.c b/nptl/tst-_res1mod1.c deleted file mode 100644 index 3af31c4c03..0000000000 --- a/nptl/tst-_res1mod1.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#undef _res - -struct __res_state _res; diff --git a/nptl/tst-_res1mod2.c b/nptl/tst-_res1mod2.c deleted file mode 100644 index d2a3509c6d..0000000000 --- a/nptl/tst-_res1mod2.c +++ /dev/null @@ -1 +0,0 @@ -/* Nothing. */ diff --git a/nptl/tst-atfork2.c b/nptl/tst-atfork2.c deleted file mode 100644 index 6e4b803413..0000000000 --- a/nptl/tst-atfork2.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Must be exported. */ -int val; - -static void -prepare (void) -{ - val *= 2; -} - -static void -parent (void) -{ - val += 4; -} - -static void -child (void) -{ - val += 8; -} - - -static int -do_test (void) -{ - mtrace (); - - if (pthread_atfork (prepare, parent, child) != 0) - { - puts ("do_test: atfork failed"); - exit (1); - } - - void *h = dlopen ("tst-atfork2mod.so", RTLD_LAZY); - if (h == NULL) - { - printf ("dlopen failed: %s\n", dlerror ()); - exit (1); - } - - /* First trial of fork. */ - pid_t pid = fork (); - if (pid == -1) - { - puts ("1st fork failed"); - exit (1); - } - - if (pid == 0) - { - /* Child. */ - if (val != 80) - { - printf ("1st: expected val=%d, got %d\n", 80, val); - exit (2); - } - - exit (0); - } - - /* Parent. */ - if (val != 24) - { - printf ("1st: expected val=%d, got %d\n", 24, val); - exit (1); - } - - int status; - if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) - { - puts ("1st waitpid failed"); - exit (1); - } - - if (status != 0) - exit (status); - - puts ("unloading now"); - - /* Unload the module. */ - if (dlclose (h) != 0) - { - puts ("dlclose failed"); - exit (1); - } - - puts ("2nd fork"); - - /* Second fork trial. */ - val = 1; - pid = fork (); - if (pid == -1) - { - puts ("2nd fork failed"); - exit (1); - } - - if (pid == 0) - { - /* Child. */ - if (val != 10) - { - printf ("2nd: expected val=%d, got %d\n", 10, val); - exit (3); - } - - exit (0); - } - - /* Parent. */ - if (val != 6) - { - printf ("2nd: expected val=%d, got %d\n", 6, val); - exit (1); - } - - if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) - { - puts ("2nd waitpid failed"); - exit (1); - } - - if (status != 0) - exit (status); - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-atfork2mod.c b/nptl/tst-atfork2mod.c deleted file mode 100644 index b307a307ec..0000000000 --- a/nptl/tst-atfork2mod.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - - -extern int val; - - -static void -prepare (void) -{ - ++val; -} - -static void -parent (void) -{ - val *= 4; -} - -static void -child (void) -{ - val *= 8; -} - -static void -__attribute__ ((constructor)) -init (void) -{ - printf ("dsohandle = %p\n", __dso_handle); - - if (pthread_atfork (prepare, parent, child) != 0) - { - puts ("init: atfork failed"); - exit (1); - } -} diff --git a/nptl/tst-fini1.c b/nptl/tst-fini1.c deleted file mode 100644 index d395fad970..0000000000 --- a/nptl/tst-fini1.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2004. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -extern void m (void); - -int -main (void) -{ - alarm (5); - - m (); - - /* The destructor is supposed to run now. Make sure that if it is - not we will notice it by using 42 as the exit code. In case the - destructor is run it will terminate with status zero. */ - return 42; -} diff --git a/nptl/tst-fini1mod.c b/nptl/tst-fini1mod.c deleted file mode 100644 index 6c10303d34..0000000000 --- a/nptl/tst-fini1mod.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2004. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - - -static void * -tf (void *arg) -{ - int fds[2]; - if (pipe (fds) != 0) - { - puts ("pipe failed"); - exit (1); - } - - char buf[10]; - read (fds[0], buf, sizeof (buf)); - - puts ("read returned"); - exit (1); -} - -static pthread_t th; - -static void -__attribute ((destructor)) -dest (void) -{ - if (pthread_cancel (th) != 0) - { - puts ("cancel failed"); - _exit (1); - } - void *r; - if (pthread_join (th, &r) != 0) - { - puts ("join failed"); - _exit (1); - } - /* Exit successfully. */ - _exit (0); -} - -void -m (void) -{ - if (pthread_create (&th, NULL, tf, NULL) != 0) - { - puts ("create failed"); - _exit (1); - } -} diff --git a/nptl/tst-tls4.c b/nptl/tst-tls4.c deleted file mode 100644 index 7fd65de79d..0000000000 --- a/nptl/tst-tls4.c +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include - -#define N 3 - -void (*test1) (void), (*test2) (void); - -pthread_barrier_t b2, b3; - -static void * -tf (void *arg) -{ - int i; - - for (i = 0; i <= (uintptr_t) arg; ++i) - { - int r = pthread_barrier_wait (&b3); - if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("tf: barrier_wait failed"); - exit (1); - } - } - - test1 (); - - for (i = 0; i < 3; ++i) - { - int r = pthread_barrier_wait (&b3); - if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("tf: barrier_wait failed"); - exit (1); - } - } - - test2 (); - - for (i = 0; i < 3 - (uintptr_t) arg; ++i) - { - int r = pthread_barrier_wait (&b3); - if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("tf: barrier_wait failed"); - exit (1); - } - } - - return NULL; -} - -static void * -tf2 (void *arg) -{ - int r = pthread_barrier_wait (&b2); - if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("tf2: barrier_wait failed"); - exit (1); - } - - int i; - for (i = 0; i < N; ++i) - tf (arg); - return NULL; -} - -int -do_test (void) -{ - pthread_t th[2]; - const char *modules[N] - = { "tst-tls4moda.so", "tst-tls4moda.so", "tst-tls4modb.so" }; - - if (pthread_barrier_init (&b2, NULL, 2) != 0) - { - puts ("barrier_init failed"); - return 1; - } - - if (pthread_barrier_init (&b3, NULL, 3) != 0) - { - puts ("barrier_init failed"); - return 1; - } - - if (pthread_create (&th[0], NULL, tf2, (void *) (uintptr_t) 1)) - { - puts ("pthread_create failed"); - return 1; - } - - int r = pthread_barrier_wait (&b2); - if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("barrier_wait failed"); - return 1; - } - - int i; - for (i = 0; i < N; ++i) - { - void *h = dlopen (modules[i], RTLD_LAZY); - if (h == NULL) - { - printf ("dlopen failed %s\n", dlerror ()); - return 1; - } - - test1 = dlsym (h, "test1"); - if (test1 == NULL) - { - printf ("dlsym for test1 failed %s\n", dlerror ()); - return 1; - } - - test2 = dlsym (h, "test2"); - if (test2 == NULL) - { - printf ("dlsym for test2 failed %s\n", dlerror ()); - return 1; - } - - if (pthread_create (&th[1], NULL, tf, (void *) (uintptr_t) 2)) - { - puts ("pthread_create failed"); - return 1; - } - - tf ((void *) (uintptr_t) 0); - - if (pthread_join (th[1], NULL) != 0) - { - puts ("join failed"); - return 1; - } - - if (dlclose (h)) - { - puts ("dlclose failed"); - return 1; - } - - printf ("test %d with %s succeeded\n", i, modules[i]); - } - - if (pthread_join (th[0], NULL) != 0) - { - puts ("join failed"); - return 1; - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-tls4moda.c b/nptl/tst-tls4moda.c deleted file mode 100644 index ccff2a797a..0000000000 --- a/nptl/tst-tls4moda.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - -static __thread unsigned char foo [32] - __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))); - -void -test1 (void) -{ - size_t s; - - for (s = 0; s < sizeof (foo); ++s) - { - if (foo [s]) - abort (); - foo [s] = s; - } -} - -void -test2 (void) -{ - size_t s; - - for (s = 0; s < sizeof (foo); ++s) - { - if (foo [s] != s) - abort (); - foo [s] = sizeof (foo) - s; - } -} diff --git a/nptl/tst-tls4modb.c b/nptl/tst-tls4modb.c deleted file mode 100644 index 2c29c2d18a..0000000000 --- a/nptl/tst-tls4modb.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - -static int i; -int bar; - -static __thread void *foo [32 / sizeof (void *)] - __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))) - = { &i, &bar }; - -void -test1 (void) -{ - size_t s; - - if (foo [0] != &i || foo [1] != &bar) - abort (); - - foo [0] = NULL; - foo [1] = NULL; - for (s = 0; s < sizeof (foo) / sizeof (void *); ++s) - { - if (foo [s]) - abort (); - foo [s] = &foo[s]; - } -} - -void -test2 (void) -{ - size_t s; - - for (s = 0; s < sizeof (foo) / sizeof (void *); ++s) - { - if (foo [s] != &foo [s]) - abort (); - foo [s] = &foo [s ^ 1]; - } -} diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index 5f9610ecbf..2d483c8534 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -117,6 +117,22 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx8 tst-cancelx10 \ tst-cancelx12 tst-cancelx14 tst-cancelx15 tst-cancelx18 \ tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 +ifeq ($(build-shared),yes) +tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 +tests-nolibpthread += tst-fini1 +endif + +modules-names += tst-atfork2mod tst-tls4moda tst-tls4modb \ + tst-_res1mod1 tst-_res1mod2 tst-fini1mod +test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names))) + +tst-atfork2mod.so-no-z-defs = yes + +ifeq ($(build-shared),yes) +# Build all the modules even when not actually running test programs. +tests: $(test-modules) +endif + tests-static += tst-locale1 tst-locale2 tests += tst-cond11-static @@ -150,6 +166,15 @@ CFLAGS-tst-pt-align3.c += $(stack-align-test-flags) tst-umask1-ARGS = $(objpfx)tst-umask1.temp +$(objpfx)tst-atfork2: $(libdl) $(shared-thread-library) +LDFLAGS-tst-atfork2 = -rdynamic +tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace +$(objpfx)tst-atfork2mod.so: $(shared-thread-library) + +ifeq ($(build-shared),yes) +$(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so +endif + ifeq ($(build-shared),yes) $(objpfx)tst-cleanup0.out: /dev/null $(objpfx)tst-cleanup0 $(make-test-out) > $@ 2>&1; \ @@ -164,7 +189,23 @@ else $(objpfx)tst-cancel28: $(common-objpfx)rt/librt.a endif +$(objpfx)tst-fini1: $(shared-thread-library) $(objpfx)tst-fini1mod.so + +$(objpfx)tst-fini1mod.so: $(shared-thread-library) + +$(objpfx)tst-_res1mod2.so: $(objpfx)tst-_res1mod1.so +LDFLAGS-tst-_res1mod1.so = -Wl,-soname,tst-_res1mod1.so +LDFLAGS-tst-_res1mod2.so = -Wl,-soname,tst-_res1mod2.so +$(objpfx)tst-_res1: $(objpfx)tst-_res1mod1.so $(objpfx)tst-_res1mod2.so \ + $(shared-thread-library) + +$(objpfx)tst-pt-tls4: $(libdl) $(shared-thread-library) +$(objpfx)tst-pt-tls4.out: $(objpfx)tst-tls4moda.so $(objpfx)tst-tls4modb.so + +generated += tst-atfork2.mtrace +generated += $(objpfx)tst-atfork2.mtrace \ + $(addsuffix .so,$(strip $(modules-names))) tests-internal += tst-robust8 diff --git a/sysdeps/pthread/tst-_res1.c b/sysdeps/pthread/tst-_res1.c new file mode 100644 index 0000000000..3e186bcb39 --- /dev/null +++ b/sysdeps/pthread/tst-_res1.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* Test whether _res in glibc 2.1.x and earlier (before __res_state() + was introduced) works. Portable programs should never do the + dirty things below. */ + +#include +#include +#include +#include + +void *tf (void *resp) +{ + if (resp == &_res || resp == __res_state ()) + abort (); + _res.retry = 24; + return NULL; +} + +void do_test (struct __res_state *resp) +{ + if (resp != &_res || resp != __res_state ()) + abort (); + if (_res.retry != 12) + abort (); +} + +int main (void) +{ +#undef _res + extern struct __res_state _res; + pthread_t th; + + _res.retry = 12; + if (pthread_create (&th, NULL, tf, &_res) != 0) + { + puts ("create failed"); + exit (1); + } + + do_test (&_res); + + if (pthread_join (th, NULL) != 0) + { + puts ("join failed"); + exit (1); + } + + do_test (&_res); + + exit (0); +} diff --git a/sysdeps/pthread/tst-_res1mod1.c b/sysdeps/pthread/tst-_res1mod1.c new file mode 100644 index 0000000000..3af31c4c03 --- /dev/null +++ b/sysdeps/pthread/tst-_res1mod1.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#undef _res + +struct __res_state _res; diff --git a/sysdeps/pthread/tst-_res1mod2.c b/sysdeps/pthread/tst-_res1mod2.c new file mode 100644 index 0000000000..d2a3509c6d --- /dev/null +++ b/sysdeps/pthread/tst-_res1mod2.c @@ -0,0 +1 @@ +/* Nothing. */ diff --git a/sysdeps/pthread/tst-atfork2.c b/sysdeps/pthread/tst-atfork2.c new file mode 100644 index 0000000000..6e4b803413 --- /dev/null +++ b/sysdeps/pthread/tst-atfork2.c @@ -0,0 +1,158 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Must be exported. */ +int val; + +static void +prepare (void) +{ + val *= 2; +} + +static void +parent (void) +{ + val += 4; +} + +static void +child (void) +{ + val += 8; +} + + +static int +do_test (void) +{ + mtrace (); + + if (pthread_atfork (prepare, parent, child) != 0) + { + puts ("do_test: atfork failed"); + exit (1); + } + + void *h = dlopen ("tst-atfork2mod.so", RTLD_LAZY); + if (h == NULL) + { + printf ("dlopen failed: %s\n", dlerror ()); + exit (1); + } + + /* First trial of fork. */ + pid_t pid = fork (); + if (pid == -1) + { + puts ("1st fork failed"); + exit (1); + } + + if (pid == 0) + { + /* Child. */ + if (val != 80) + { + printf ("1st: expected val=%d, got %d\n", 80, val); + exit (2); + } + + exit (0); + } + + /* Parent. */ + if (val != 24) + { + printf ("1st: expected val=%d, got %d\n", 24, val); + exit (1); + } + + int status; + if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) + { + puts ("1st waitpid failed"); + exit (1); + } + + if (status != 0) + exit (status); + + puts ("unloading now"); + + /* Unload the module. */ + if (dlclose (h) != 0) + { + puts ("dlclose failed"); + exit (1); + } + + puts ("2nd fork"); + + /* Second fork trial. */ + val = 1; + pid = fork (); + if (pid == -1) + { + puts ("2nd fork failed"); + exit (1); + } + + if (pid == 0) + { + /* Child. */ + if (val != 10) + { + printf ("2nd: expected val=%d, got %d\n", 10, val); + exit (3); + } + + exit (0); + } + + /* Parent. */ + if (val != 6) + { + printf ("2nd: expected val=%d, got %d\n", 6, val); + exit (1); + } + + if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) + { + puts ("2nd waitpid failed"); + exit (1); + } + + if (status != 0) + exit (status); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-atfork2mod.c b/sysdeps/pthread/tst-atfork2mod.c new file mode 100644 index 0000000000..b307a307ec --- /dev/null +++ b/sysdeps/pthread/tst-atfork2mod.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + + +extern int val; + + +static void +prepare (void) +{ + ++val; +} + +static void +parent (void) +{ + val *= 4; +} + +static void +child (void) +{ + val *= 8; +} + +static void +__attribute__ ((constructor)) +init (void) +{ + printf ("dsohandle = %p\n", __dso_handle); + + if (pthread_atfork (prepare, parent, child) != 0) + { + puts ("init: atfork failed"); + exit (1); + } +} diff --git a/sysdeps/pthread/tst-fini1.c b/sysdeps/pthread/tst-fini1.c new file mode 100644 index 0000000000..d395fad970 --- /dev/null +++ b/sysdeps/pthread/tst-fini1.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +extern void m (void); + +int +main (void) +{ + alarm (5); + + m (); + + /* The destructor is supposed to run now. Make sure that if it is + not we will notice it by using 42 as the exit code. In case the + destructor is run it will terminate with status zero. */ + return 42; +} diff --git a/sysdeps/pthread/tst-fini1mod.c b/sysdeps/pthread/tst-fini1mod.c new file mode 100644 index 0000000000..6c10303d34 --- /dev/null +++ b/sysdeps/pthread/tst-fini1mod.c @@ -0,0 +1,71 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + + +static void * +tf (void *arg) +{ + int fds[2]; + if (pipe (fds) != 0) + { + puts ("pipe failed"); + exit (1); + } + + char buf[10]; + read (fds[0], buf, sizeof (buf)); + + puts ("read returned"); + exit (1); +} + +static pthread_t th; + +static void +__attribute ((destructor)) +dest (void) +{ + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + _exit (1); + } + void *r; + if (pthread_join (th, &r) != 0) + { + puts ("join failed"); + _exit (1); + } + /* Exit successfully. */ + _exit (0); +} + +void +m (void) +{ + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("create failed"); + _exit (1); + } +} diff --git a/sysdeps/pthread/tst-pt-tls4.c b/sysdeps/pthread/tst-pt-tls4.c new file mode 100644 index 0000000000..7fd65de79d --- /dev/null +++ b/sysdeps/pthread/tst-pt-tls4.c @@ -0,0 +1,180 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include + +#define N 3 + +void (*test1) (void), (*test2) (void); + +pthread_barrier_t b2, b3; + +static void * +tf (void *arg) +{ + int i; + + for (i = 0; i <= (uintptr_t) arg; ++i) + { + int r = pthread_barrier_wait (&b3); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("tf: barrier_wait failed"); + exit (1); + } + } + + test1 (); + + for (i = 0; i < 3; ++i) + { + int r = pthread_barrier_wait (&b3); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("tf: barrier_wait failed"); + exit (1); + } + } + + test2 (); + + for (i = 0; i < 3 - (uintptr_t) arg; ++i) + { + int r = pthread_barrier_wait (&b3); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("tf: barrier_wait failed"); + exit (1); + } + } + + return NULL; +} + +static void * +tf2 (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("tf2: barrier_wait failed"); + exit (1); + } + + int i; + for (i = 0; i < N; ++i) + tf (arg); + return NULL; +} + +int +do_test (void) +{ + pthread_t th[2]; + const char *modules[N] + = { "tst-tls4moda.so", "tst-tls4moda.so", "tst-tls4modb.so" }; + + if (pthread_barrier_init (&b2, NULL, 2) != 0) + { + puts ("barrier_init failed"); + return 1; + } + + if (pthread_barrier_init (&b3, NULL, 3) != 0) + { + puts ("barrier_init failed"); + return 1; + } + + if (pthread_create (&th[0], NULL, tf2, (void *) (uintptr_t) 1)) + { + puts ("pthread_create failed"); + return 1; + } + + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("barrier_wait failed"); + return 1; + } + + int i; + for (i = 0; i < N; ++i) + { + void *h = dlopen (modules[i], RTLD_LAZY); + if (h == NULL) + { + printf ("dlopen failed %s\n", dlerror ()); + return 1; + } + + test1 = dlsym (h, "test1"); + if (test1 == NULL) + { + printf ("dlsym for test1 failed %s\n", dlerror ()); + return 1; + } + + test2 = dlsym (h, "test2"); + if (test2 == NULL) + { + printf ("dlsym for test2 failed %s\n", dlerror ()); + return 1; + } + + if (pthread_create (&th[1], NULL, tf, (void *) (uintptr_t) 2)) + { + puts ("pthread_create failed"); + return 1; + } + + tf ((void *) (uintptr_t) 0); + + if (pthread_join (th[1], NULL) != 0) + { + puts ("join failed"); + return 1; + } + + if (dlclose (h)) + { + puts ("dlclose failed"); + return 1; + } + + printf ("test %d with %s succeeded\n", i, modules[i]); + } + + if (pthread_join (th[0], NULL) != 0) + { + puts ("join failed"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-tls4moda.c b/sysdeps/pthread/tst-tls4moda.c new file mode 100644 index 0000000000..ccff2a797a --- /dev/null +++ b/sysdeps/pthread/tst-tls4moda.c @@ -0,0 +1,49 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static __thread unsigned char foo [32] + __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))); + +void +test1 (void) +{ + size_t s; + + for (s = 0; s < sizeof (foo); ++s) + { + if (foo [s]) + abort (); + foo [s] = s; + } +} + +void +test2 (void) +{ + size_t s; + + for (s = 0; s < sizeof (foo); ++s) + { + if (foo [s] != s) + abort (); + foo [s] = sizeof (foo) - s; + } +} diff --git a/sysdeps/pthread/tst-tls4modb.c b/sysdeps/pthread/tst-tls4modb.c new file mode 100644 index 0000000000..2c29c2d18a --- /dev/null +++ b/sysdeps/pthread/tst-tls4modb.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static int i; +int bar; + +static __thread void *foo [32 / sizeof (void *)] + __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))) + = { &i, &bar }; + +void +test1 (void) +{ + size_t s; + + if (foo [0] != &i || foo [1] != &bar) + abort (); + + foo [0] = NULL; + foo [1] = NULL; + for (s = 0; s < sizeof (foo) / sizeof (void *); ++s) + { + if (foo [s]) + abort (); + foo [s] = &foo[s]; + } +} + +void +test2 (void) +{ + size_t s; + + for (s = 0; s < sizeof (foo) / sizeof (void *); ++s) + { + if (foo [s] != &foo [s]) + abort (); + foo [s] = &foo [s ^ 1]; + } +} -- cgit 1.4.1