xref: /netbsd-src/external/gpl3/gcc.old/dist/libphobos/testsuite/libphobos.thread/fiber_guard_page.d (revision aef5eb5f59cdfe8314f1b5f78ac04eb144e44010)
1 // { dg-shouldfail "segv or bus error" }
2 import core.thread;
3 import core.sys.posix.sys.mman;
4 
5 // this should be true for most architectures
6 // (taken from core.thread)
7 version = StackGrowsDown;
8 
9 enum stackSize = 4096;
10 
11 // Simple method that causes a stack overflow
12 void stackMethod()
13 {
14     // Over the stack size, so it overflows the stack
15     int[stackSize/int.sizeof+100] x;
16 }
17 
18 void main()
19 {
20     auto test_fiber = new Fiber(&stackMethod, stackSize);
21 
22     // allocate a page below (above) the fiber's stack to make stack overflows possible (w/o segfaulting)
23     version (StackGrowsDown)
24     {
25         static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem");
26         auto stackBottom = test_fiber.tupleof[8];
27         auto p = mmap(stackBottom - 8 * stackSize, 8 * stackSize,
28                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
29         assert(p !is null, "failed to allocate page");
30     }
31     else
32     {
33         auto m_sz = test_fiber.tupleof[7];
34         auto m_pmem = test_fiber.tupleof[8];
35         static assert(__traits(identifier, test_fiber.tupleof[7]) == "m_size");
36         static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem");
37 
38         auto stackTop = m_pmem + m_sz;
39         auto p = mmap(stackTop, 8 * stackSize,
40                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
41         assert(p !is null, "failed to allocate page");
42     }
43 
44     // the guard page should prevent a mem corruption by stack
45     // overflow and cause a segfault instead (or generate SIGBUS on *BSD flavors)
46     test_fiber.call();
47 }
48