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