Allocate some memory that can be used as a stack.
    @return: a ctypes void pointer to the *top* of the stack.

def allocate_stack(size=DEFAULT_STACK_SIZE):
    """Allocate some memory that can be used as a stack.
    @return: a ctypes void pointer to the *top* of the stack.
    """
    # Allocate memory with appropriate flags for a stack as in https://blog.fefe.de/?ts=a85c8ba7
    base = libc.mmap(
        None,
        size + GUARD_PAGE_SIZE,
        libc.PROT_READ | libc.PROT_WRITE,
        libc.MAP_PRIVATE | libc.MAP_ANONYMOUS | libc.MAP_GROWSDOWN | libc.MAP_STACK,
        -1, 0)

    try:
        # create a guard page that crashes the application when it is written to (on stack overflow)
        libc.mprotect(base, GUARD_PAGE_SIZE, libc.PROT_NONE)

        yield ctypes.c_void_p(base + size + GUARD_PAGE_SIZE)
    finally:
        libc.munmap(base, size + GUARD_PAGE_SIZE)