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