diff options
author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-24 20:22:12 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-24 20:22:12 +0200 |
commit | 7988979a722b4cdf287b2093956a76a3f19b9897 (patch) | |
tree | d35e251d0472ceca55a2eef61cff261c8ee68fab /test/setjmp |
add uClibc-ng test directory
Diffstat (limited to 'test/setjmp')
-rw-r--r-- | test/setjmp/Makefile | 8 | ||||
-rw-r--r-- | test/setjmp/Makefile.in | 0 | ||||
-rw-r--r-- | test/setjmp/bug269-setjmp.c | 106 | ||||
-rw-r--r-- | test/setjmp/jmpbug.c | 51 | ||||
-rw-r--r-- | test/setjmp/sigjmpbug.c | 51 | ||||
-rw-r--r-- | test/setjmp/tst-setjmp.c | 118 | ||||
-rw-r--r-- | test/setjmp/tst-vfork-longjmp.c | 108 |
7 files changed, 442 insertions, 0 deletions
diff --git a/test/setjmp/Makefile b/test/setjmp/Makefile new file mode 100644 index 0000000..6feab59 --- /dev/null +++ b/test/setjmp/Makefile @@ -0,0 +1,8 @@ +# uClibc setjmp tests +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + +top_builddir=../../ +top_srcdir=../../ +include ../Rules.mak +-include Makefile.in +include ../Test.mak diff --git a/test/setjmp/Makefile.in b/test/setjmp/Makefile.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/setjmp/Makefile.in diff --git a/test/setjmp/bug269-setjmp.c b/test/setjmp/bug269-setjmp.c new file mode 100644 index 0000000..a9254a1 --- /dev/null +++ b/test/setjmp/bug269-setjmp.c @@ -0,0 +1,106 @@ +/* Copyright (C) 2004 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 + 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 + <http://www.gnu.org/licenses/>. */ + +/* Test case for Bugzilla # 269 */ + +#include <stdio.h> +#include <setjmp.h> +#include <stdlib.h> + +jmp_buf buf1; +jmp_buf buf2; +int *p; +int n_x = 6; + +static int g_counter = 0; + +static int +f (void) +{ + static int counter = 0; + static int way_point1 = 3; + static int way_point2 = 2; + int lose = 0; + + if (setjmp (buf1) != 101) + { + int a[n_x]; /* reallocate stack space */ + g_counter++; + p = &a[0]; + if (g_counter < 5) + longjmp (buf1, 2); + else if (g_counter == 5) + longjmp (buf1, 101); + else + { + _setjmp (buf2); + _longjmp (buf1, 101); + } + } + + way_point1--; + + if (counter == 0) + { + counter++; + { + int a[n_x]; /* reallocate stack space */ + g_counter++; + p = &a[0]; + if (g_counter < 5) + longjmp (buf1, 2); + else if (g_counter == 5) + longjmp (buf1, 101); + else + { + _setjmp (buf2); + _longjmp (buf1, 101); + } + } + } + + way_point2--; + + if (counter == 1) + { + counter++; + longjmp (buf2, 2); + } + + lose = !(way_point1 == 0 && way_point2 == 0 + && g_counter == 6 && counter == 2); + + return lose; +} + +static int +do_test (void) +{ + int lose; + + lose = f (); + + if (lose) + puts ("Test FAILED!"); + else + puts ("Test succeeded!"); + + return lose ? EXIT_FAILURE : EXIT_SUCCESS; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/setjmp/jmpbug.c b/test/setjmp/jmpbug.c new file mode 100644 index 0000000..da087a7 --- /dev/null +++ b/test/setjmp/jmpbug.c @@ -0,0 +1,51 @@ +/* setjmp vs alloca test case. Exercised bug on sparc. */ + +#include <stdio.h> +#include <setjmp.h> +#include <alloca.h> + +int ret; +int verbose; + +__attribute__ ((__noreturn__)) +static void +sub5 (jmp_buf buf) +{ + longjmp (buf, 1); +} + +static void +test (int x) +{ + jmp_buf buf; + char *foo; + int arr[100]; + + ++ret; + + arr[77] = x; + if (setjmp (buf)) + { + --ret; + if (verbose) + printf ("made it ok; %d\n", arr[77]); + return; + } + + foo = (char *) alloca (128); + sub5 (buf); +} + +int +main (int argc, char *argv[]) +{ + int i; + + verbose = (argc != 1); + ret = 0; + + for (i = 123; i < 345; ++i) + test (i); + + return ret; +} diff --git a/test/setjmp/sigjmpbug.c b/test/setjmp/sigjmpbug.c new file mode 100644 index 0000000..5b17181 --- /dev/null +++ b/test/setjmp/sigjmpbug.c @@ -0,0 +1,51 @@ +/* sigsetjmp vs alloca test case. Exercised bug on sparc. */ + +#include <stdio.h> +#include <setjmp.h> +#include <alloca.h> + +int ret; +int verbose; + +__attribute__ ((__noreturn__)) +static void +sub5 (jmp_buf buf) +{ + siglongjmp (buf, 1); +} + +static void +test (int x) +{ + sigjmp_buf buf; + char *foo; + int arr[100]; + + ++ret; + + arr[77] = x; + if (sigsetjmp (buf, 1)) + { + --ret; + if (verbose) + printf ("made it ok; %d\n", arr[77]); + return; + } + + foo = (char *) alloca (128); + sub5 (buf); +} + +int +main (int argc, char *argv[]) +{ + int i; + + verbose = (argc != 1); + ret = 0; + + for (i = 123; i < 345; ++i) + test (i); + + return ret; +} diff --git a/test/setjmp/tst-setjmp.c b/test/setjmp/tst-setjmp.c new file mode 100644 index 0000000..ea1c29a --- /dev/null +++ b/test/setjmp/tst-setjmp.c @@ -0,0 +1,118 @@ +/* Copyright (C) 1991, 1992, 1997, 1998, 2000 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 + 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 + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <setjmp.h> +#include <stdlib.h> + +static jmp_buf env; +static int last_value = -1, lose = 0; + +__attribute__ ((__noreturn__)) +static void +jump (int val) +{ + longjmp (env, val); +} + +int +main (void) +{ + int value; + + value = setjmp (env); + if (value != last_value + 1) + { + fputs("Shouldn't have ", stdout); + lose = 1; + } + last_value = value; + switch (value) + { + case 0: + puts("Saved environment."); + jump (0); + default: + printf ("Jumped to %d.\n", value); + if (value < 10) + jump (value + 1); + } + + if (!lose && value == 10) + { + /* Do a second test, this time without `setjmp' being a macro. + This is not required by ISO C but we have this for compatibility. */ +#undef setjmp + extern int setjmp (jmp_buf); + + last_value = -1; + lose = 0; + + value = setjmp (env); + if (value != last_value + 1) + { + fputs("Shouldn't have ", stdout); + lose = 1; + } + last_value = value; + switch (value) + { + case 0: + puts("Saved environment."); + jump (0); + default: + printf ("Jumped to %d.\n", value); + if (value < 10) + jump (value + 1); + } + } + + if (!lose && value == 10) + { + /* And again for the `_setjmp' function. */ +#ifndef _setjmp + extern int _setjmp (jmp_buf); +#endif + last_value = -1; + lose = 0; + + value = _setjmp (env); + if (value != last_value + 1) + { + fputs("Shouldn't have ", stdout); + lose = 1; + } + last_value = value; + switch (value) + { + case 0: + puts("Saved environment."); + jump (0); + default: + printf ("Jumped to %d.\n", value); + if (value < 10) + jump (value + 1); + } + } + + if (lose || value != 10) + puts ("Test FAILED!"); + else + puts ("Test succeeded!"); + + return lose ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/test/setjmp/tst-vfork-longjmp.c b/test/setjmp/tst-vfork-longjmp.c new file mode 100644 index 0000000..2784424 --- /dev/null +++ b/test/setjmp/tst-vfork-longjmp.c @@ -0,0 +1,108 @@ +/* make sure we can vfork/exec across setjmp/longjmp's + * and make sure signal block masks don't get corrupted + * in the process. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <unistd.h> +#include <errno.h> +#include <setjmp.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <string.h> + +int verbose = 0; + +static int execute_child(const char *prog) +{ + int status; + pid_t child; + child = vfork(); + if (child == 0) { + execlp(prog, prog, NULL); + perror("Could not execute specified prog"); + _exit(1); + } else if (child == 1) + return 1; + wait(&status); + return WEXITSTATUS(status); +} + +sigset_t orig_mask; + +static int check_sig_mask(void) +{ + int status; + pid_t child; + + child = vfork(); + if (child == 0) { + int ret; + sigset_t child_mask; + memset(&child_mask, 0x00, sizeof(child_mask)); + ret = sigprocmask(SIG_BLOCK, NULL, &child_mask); + if (ret != 0) { + perror("could not get child sig block mask"); + _exit(1); + } + ret = memcmp(&orig_mask, &child_mask, sizeof(orig_mask)); + if (verbose) { + printf("sigmsk: %08lx%08lx ", child_mask.__val[1], child_mask.__val[0]); + printf("sigmsk: %08lx%08lx ", orig_mask.__val[1], orig_mask.__val[0]); + printf("%i\n", ret); + } + _exit(ret); + } else if (child == 1) + return 1; + wait(&status); + return WEXITSTATUS(status); +} + +int main(int argc, char *argv[]) +{ + const char *prog; + jmp_buf env; + sigjmp_buf sigenv; + int max; + /* values modified between setjmp/longjmp cannot be local to this func */ + static int cnt, ret; + + memset(&orig_mask, 0x00, sizeof(orig_mask)); + ret = sigprocmask(SIG_BLOCK, NULL, &orig_mask); + if (ret != 0) { + perror("could not get orig sig block mask"); + return 1; + } + + prog = (argc > 1 ? argv[1] : "true"); + ret = 0; + verbose = 0; + max = 10; + + /* test vfork()/exec() inside of sigsetjmp/siglongjmp */ + cnt = 0; + sigsetjmp(sigenv, 1); + ++cnt; + if (verbose) + printf("sigsetjmp loop %i\n", cnt); + ret |= check_sig_mask(); + ret |= execute_child(prog); + if (cnt < max) + siglongjmp(sigenv, 0); + + /* test vfork()/sigprocmask() inside of setjmp/longjmp */ + cnt = 0; + setjmp(env); + ++cnt; + if (verbose) + printf("setjmp loop %i\n", cnt); + ret |= check_sig_mask(); + ret |= execute_child(prog); + if (cnt < max) + longjmp(env, 0); + + return ret; +} |