1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2011-2023 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 /* Based on the gcc testcase `gcc/testsuite/gcc.dg/split-1.c'. This test 19 needs to use setrlimit to set the stack size, so it can only run on Unix. 20 */ 21 22 #include <stdlib.h> 23 #include <sys/types.h> 24 #include <sys/resource.h> 25 #include <stdio.h> 26 #include <sys/mman.h> 27 28 /* Use a noinline function to ensure that the buffer is not removed 29 from the stack. */ 30 static void use_buffer (char *buf) __attribute__ ((noinline)); 31 static void 32 use_buffer (char *buf) 33 { 34 buf[0] = '\0'; 35 } 36 37 static volatile int marker_var; 38 39 static void 40 marker_miss (void) 41 { 42 marker_var = 0; 43 } 44 45 static void 46 marker_hit (void) 47 { 48 marker_var = 0; 49 } 50 51 void *reserved; 52 #define RESERVED_SIZE 0x1000000 53 54 /* Each recursive call uses 10,000 bytes. We call it 1000 times, 55 using a total of 10,000,000 bytes. If -fsplit-stack is not 56 working, that will overflow our stack limit. */ 57 58 static void 59 down (int i) 60 { 61 char buf[10000]; 62 static void *last; 63 64 if (last && last < (void *) buf) 65 marker_hit (); 66 last = buf; 67 68 if (i == 500) 69 { 70 if (munmap (reserved, RESERVED_SIZE) != 0) 71 abort (); 72 reserved = NULL; 73 } 74 75 if (i > 0) 76 { 77 use_buffer (buf); 78 down (i - 1); 79 } 80 else 81 marker_miss (); 82 } 83 84 int 85 main (void) 86 { 87 struct rlimit r; 88 89 reserved = mmap (NULL, RESERVED_SIZE, PROT_READ | PROT_WRITE, 90 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 91 if (reserved == MAP_FAILED) 92 abort (); 93 94 /* We set a stack limit because we are usually invoked via make, and 95 make sets the stack limit to be as large as possible. */ 96 r.rlim_cur = 8192 * 1024; 97 r.rlim_max = 8192 * 1024; 98 if (setrlimit (RLIMIT_STACK, &r) != 0) 99 abort (); 100 down (1000); 101 return 0; 102 } 103