1/* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2015-2020 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18#include <assert.h> 19#include <pthread.h> 20#include <unistd.h> 21#include <setjmp.h> 22 23/* Number of threads. */ 24#define NTHREADS 10 25 26/* When set, threads exit. */ 27volatile int break_out; 28 29pthread_barrier_t barrier; 30 31/* Entry point for threads that setjmp/longjmp. */ 32 33static void * 34thread_longjmp (void *arg) 35{ 36 jmp_buf env; 37 38 pthread_barrier_wait (&barrier); 39 40 while (!break_out) 41 { 42 if (setjmp (env) == 0) 43 longjmp (env, 1); 44 45 usleep (1); 46 } 47 return NULL; 48} 49 50/* Entry point for threads that try/catch. */ 51 52static void * 53thread_try_catch (void *arg) 54{ 55 volatile unsigned int counter = 0; 56 57 pthread_barrier_wait (&barrier); 58 59 while (!break_out) 60 { 61 try 62 { 63 throw 1; 64 } 65 catch (...) 66 { 67 counter++; 68 } 69 70 usleep (1); 71 } 72 return NULL; 73} 74 75int 76main (void) 77{ 78 pthread_t threads[NTHREADS]; 79 int i; 80 int ret; 81 82 /* Don't run forever. */ 83 alarm (180); 84 85 pthread_barrier_init (&barrier, NULL, NTHREADS + 1); 86 87 for (i = 0; i < NTHREADS; i++) 88 { 89 /* Half of the threads does setjmp/longjmp, the other half does 90 try/catch. */ 91 if ((i % 2) == 0) 92 ret = pthread_create (&threads[i], NULL, thread_longjmp , NULL); 93 else 94 ret = pthread_create (&threads[i], NULL, thread_try_catch , NULL); 95 assert (ret == 0); 96 } 97 98 /* Wait until all threads are running. */ 99 pthread_barrier_wait (&barrier); 100 101#define LINE usleep (1) 102 103 /* The other thread's setjmp/longjmp/try/catch should not disturb 104 this thread's stepping over these lines. */ 105 106 LINE; /* set break here */ 107 LINE; /* line 1 */ 108 LINE; /* line 2 */ 109 LINE; /* line 3 */ 110 LINE; /* line 4 */ 111 LINE; /* line 5 */ 112 LINE; /* line 6 */ 113 LINE; /* line 7 */ 114 LINE; /* line 8 */ 115 LINE; /* line 9 */ 116 LINE; /* line 10 */ 117 118 break_out = 1; 119 120 for (i = 0; i < NTHREADS; i++) 121 { 122 ret = pthread_join (threads[i], NULL); 123 assert (ret == 0); 124 } 125 126 return 0; 127} 128