1*0bfacb9bSmrg // { dg-options "-O0" }
2760c2415Smrg // { dg-shouldfail "segv or bus error" }
3760c2415Smrg import core.thread;
4760c2415Smrg import core.sys.posix.sys.mman;
5760c2415Smrg 
6760c2415Smrg // this should be true for most architectures
7760c2415Smrg // (taken from core.thread)
8760c2415Smrg version = StackGrowsDown;
9760c2415Smrg 
10760c2415Smrg enum stackSize = 4096;
11760c2415Smrg 
12760c2415Smrg // Simple method that causes a stack overflow
stackMethod()13760c2415Smrg void stackMethod()
14760c2415Smrg {
15760c2415Smrg     // Over the stack size, so it overflows the stack
16760c2415Smrg     int[stackSize/int.sizeof+100] x;
17760c2415Smrg }
18760c2415Smrg 
main()19760c2415Smrg void main()
20760c2415Smrg {
21*0bfacb9bSmrg     auto test_fiber = new Fiber(&stackMethod, stackSize, stackSize);
22760c2415Smrg 
23760c2415Smrg     // allocate a page below (above) the fiber's stack to make stack overflows possible (w/o segfaulting)
24760c2415Smrg     version (StackGrowsDown)
25760c2415Smrg     {
26760c2415Smrg         static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem");
27760c2415Smrg         auto stackBottom = test_fiber.tupleof[8];
28760c2415Smrg         auto p = mmap(stackBottom - 8 * stackSize, 8 * stackSize,
29760c2415Smrg                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
30760c2415Smrg         assert(p !is null, "failed to allocate page");
31760c2415Smrg     }
32760c2415Smrg     else
33760c2415Smrg     {
34760c2415Smrg         auto m_sz = test_fiber.tupleof[7];
35760c2415Smrg         auto m_pmem = test_fiber.tupleof[8];
36760c2415Smrg         static assert(__traits(identifier, test_fiber.tupleof[7]) == "m_size");
37760c2415Smrg         static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem");
38760c2415Smrg 
39760c2415Smrg         auto stackTop = m_pmem + m_sz;
40760c2415Smrg         auto p = mmap(stackTop, 8 * stackSize,
41760c2415Smrg                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
42760c2415Smrg         assert(p !is null, "failed to allocate page");
43760c2415Smrg     }
44760c2415Smrg 
45760c2415Smrg     // the guard page should prevent a mem corruption by stack
46760c2415Smrg     // overflow and cause a segfault instead (or generate SIGBUS on *BSD flavors)
47760c2415Smrg     test_fiber.call();
48760c2415Smrg }
49