1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2009-2014 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 Do not use threads as we need to exploit a bug in LWP code masked by the 19 threads code otherwise. 20 21 INFERIOR_PTID must point to exited LWP. Here we use the initial LWP as it 22 is automatically INFERIOR_PTID for GDB. 23 24 Finally we need to call target_resume (RESUME_ALL, ...) which we invoke by 25 NEW_THREAD_EVENT (called from the new LWP as initial LWP is exited now). */ 26 27 #define _GNU_SOURCE 28 #include <sched.h> 29 #include <assert.h> 30 #include <unistd.h> 31 #include <stdlib.h> 32 33 #include <features.h> 34 #ifdef __UCLIBC__ 35 #if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__)) 36 #define HAS_NOMMU 37 #endif 38 #endif 39 40 #define STACK_SIZE 0x1000 41 42 static int 43 fn_return (void *unused) 44 { 45 return 0; /* at-fn_return */ 46 } 47 48 static int 49 fn (void *unused) 50 { 51 int i; 52 unsigned char *stack; 53 int new_pid; 54 55 i = sleep (1); 56 assert (i == 0); 57 58 stack = malloc (STACK_SIZE); 59 assert (stack != NULL); 60 61 new_pid = clone (fn_return, stack + STACK_SIZE, CLONE_FILES 62 #if defined(__UCLIBC__) && defined(HAS_NOMMU) 63 | CLONE_VM 64 #endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */ 65 , NULL, NULL, NULL, NULL); 66 assert (new_pid > 0); 67 68 return 0; 69 } 70 71 int 72 main (int argc, char **argv) 73 { 74 unsigned char *stack; 75 int new_pid; 76 77 stack = malloc (STACK_SIZE); 78 assert (stack != NULL); 79 80 new_pid = clone (fn, stack + STACK_SIZE, CLONE_FILES 81 #if defined(__UCLIBC__) && defined(HAS_NOMMU) 82 | CLONE_VM 83 #endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */ 84 , NULL, NULL, NULL, NULL); 85 assert (new_pid > 0); 86 87 return 0; 88 } 89