Implement correct RLIMIT_STACK handling
* miscfuncs.cc (struct pthread_wrapper_arg): Add member guardsize. (pthread_wrapper): Set thread stack guarantee according to guardsize. Tweak assembler code so that $rax/$eax is not required by GCC to prepare the wrapper_arg value. (CygwinCreateThread): Fix deadzone handling. Drop setting a "POSIX" guardpage (aka page w/ PAGE_NOACCESS). Always use Windows guard pages instead. On post-XP systems (providing SetThreadStackGuarantee) always set up stack Windows like with reserved/commited areas and movable guard pages. Only on XP set up stack fully commited if the guardpage size is not the default system guardpage size. Fill out pthread_wrapper_arg::guardsize. Improve comments. * resource.cc: Implement RSTACK_LIMIT Linux-like. (DEFAULT_STACKSIZE): New macro. (DEFAULT_STACKGUARD): Ditto. (rlimit_stack_guard): New muto. (rlimit_stack): New global variable holding current RSTACK_LIMIT values. (__set_rlimit_stack): Set rlimit_stack under lock. (__get_rlimit_stack): Initialize rlimit_stack from executable header and return rlimit_stack values under lock. (get_rlimit_stack): Filtering function to return useful default stacksize from rlimit_stack.rlim_cur value. (getrlimit): Call __get_rlimit_stack in RLIMIT_STACK case. (setrlimit): Call __set_rlimit_stack in RLIMIT_STACK case. * thread.cc (pthread::create): Fetch default stacksize calling get_rlimit_stack. (pthread_attr::pthread_attr): Fetch default guardsize calling wincap.def_guard_page_size. (pthread_attr_getstacksize): Fetch default stacksize calling get_rlimit_stack. * thread.h (PTHREAD_DEFAULT_STACKSIZE): Remove. (PTHREAD_DEFAULT_GUARDSIZE): Remove. (get_rlimit_stack): Declare. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
@ -475,7 +475,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
||||
mutex.lock ();
|
||||
/* stackaddr holds the uppermost stack address. See the comments in
|
||||
pthread_attr_setstack and pthread_attr_setstackaddr for a description. */
|
||||
ULONG stacksize = attr.stacksize ?: PTHREAD_DEFAULT_STACKSIZE;
|
||||
ULONG stacksize = attr.stacksize ?: get_rlimit_stack ();
|
||||
PVOID stackaddr = attr.stackaddr ? ((caddr_t) attr.stackaddr - stacksize)
|
||||
: NULL;
|
||||
win32_obj_id = CygwinCreateThread (thread_init_wrapper, this, stackaddr,
|
||||
@ -1093,7 +1093,7 @@ pthread::resume ()
|
||||
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
|
||||
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
|
||||
inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), stacksize (0),
|
||||
guardsize (PTHREAD_DEFAULT_GUARDSIZE)
|
||||
guardsize (wincap.def_guard_page_size ())
|
||||
{
|
||||
schedparam.sched_priority = 0;
|
||||
}
|
||||
@ -2330,7 +2330,7 @@ pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
|
||||
/* If the stacksize has not been set by the application, return the
|
||||
default stacksize. Note that this is different from what
|
||||
pthread_attr_getstack returns. */
|
||||
*size = (*attr)->stacksize ?: PTHREAD_DEFAULT_STACKSIZE;
|
||||
*size = (*attr)->stacksize ?: get_rlimit_stack ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user