// { dg-options "-O0" } // { dg-shouldfail "segv or bus error" } import core.thread; import core.sys.posix.sys.mman; // this should be true for most architectures // (taken from core.thread) version = StackGrowsDown; enum stackSize = 4096; // Simple method that causes a stack overflow void stackMethod() { // Over the stack size, so it overflows the stack int[stackSize/int.sizeof+100] x; } void main() { auto test_fiber = new Fiber(&stackMethod, stackSize, stackSize); // allocate a page below (above) the fiber's stack to make stack overflows possible (w/o segfaulting) version (StackGrowsDown) { static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem"); auto stackBottom = test_fiber.tupleof[8]; auto p = mmap(stackBottom - 8 * stackSize, 8 * stackSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); assert(p !is null, "failed to allocate page"); } else { auto m_sz = test_fiber.tupleof[7]; auto m_pmem = test_fiber.tupleof[8]; static assert(__traits(identifier, test_fiber.tupleof[7]) == "m_size"); static assert(__traits(identifier, test_fiber.tupleof[8]) == "m_pmem"); auto stackTop = m_pmem + m_sz; auto p = mmap(stackTop, 8 * stackSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); assert(p !is null, "failed to allocate page"); } // the guard page should prevent a mem corruption by stack // overflow and cause a segfault instead (or generate SIGBUS on *BSD flavors) test_fiber.call(); } |