1/* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2011 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. */ 30static void use_buffer (char *buf) __attribute__ ((noinline)); 31static void 32use_buffer (char *buf) 33{ 34 buf[0] = '\0'; 35} 36 37static volatile int marker_var; 38 39static void 40marker_miss (void) 41{ 42 marker_var = 0; 43} 44 45static void 46marker_hit (void) 47{ 48 marker_var = 0; 49} 50 51void *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 58static void 59down (int i) 60{ 61 char buf[10000]; 62 static void *last; 63 64 if (last && last < (void *) buf) 65 { 66 printf ("%d: %p < %p\n", i, last, buf); 67 marker_hit (); 68 } 69 last = buf; 70 71 if (i == 500) 72 { 73 if (munmap (reserved, RESERVED_SIZE) != 0) 74 abort (); 75 reserved = NULL; 76 } 77 78 if (i > 0) 79 { 80 use_buffer (buf); 81 down (i - 1); 82 } 83 else 84 marker_miss (); 85} 86 87int 88main (void) 89{ 90 struct rlimit r; 91 92 reserved = mmap (NULL, RESERVED_SIZE, PROT_READ | PROT_WRITE, 93 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 94 if (reserved == MAP_FAILED) 95 abort (); 96 97 /* We set a stack limit because we are usually invoked via make, and 98 make sets the stack limit to be as large as possible. */ 99 r.rlim_cur = 8192 * 1024; 100 r.rlim_max = 8192 * 1024; 101 if (setrlimit (RLIMIT_STACK, &r) != 0) 102 abort (); 103 down (1000); 104 return 0; 105} 106