@@ -136,9 +136,20 @@ int pthread_create(pthread_t* thread, pthread_attr_t const* attributes, void* (*
136
136
if (0 != (used_attributes->stack_size % required_stack_alignment))
137
137
used_attributes->stack_size += required_stack_alignment - (used_attributes->stack_size % required_stack_alignment);
138
138
139
- used_attributes->stack_location = mmap_with_name (nullptr , used_attributes->stack_size , PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, 0 , 0 , " Thread stack" );
140
- if (!used_attributes->stack_location )
139
+ // According to POSIX, if the stack address attribute has been set in attr,
140
+ // then the guard size attribute is ignored: it is the application's responsibility
141
+ // to handle stack overflow.
142
+ size_t total_size = used_attributes->stack_size + used_attributes->guard_page_size ;
143
+ void * memory_location = mmap_with_name (nullptr , total_size, used_attributes->guard_page_size == 0 ? PROT_READ | PROT_WRITE : PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, 0 , 0 , " Thread stack" );
144
+ if (!memory_location)
141
145
return -1 ;
146
+ if (used_attributes->guard_page_size > 0 ) {
147
+ if (mprotect ((void *)((FlatPtr)memory_location + used_attributes->guard_page_size ), used_attributes->stack_size , PROT_READ | PROT_WRITE) < 0 ) {
148
+ munmap (memory_location, total_size);
149
+ return -1 ;
150
+ }
151
+ }
152
+ used_attributes->stack_location = (void *)((FlatPtr)memory_location + used_attributes->guard_page_size );
142
153
}
143
154
144
155
dbgln_if (PTHREAD_DEBUG, " pthread_create: Creating thread with attributes at {}, detach state {}, priority {}, guard page size {}, stack size {}, stack location {}" ,
0 commit comments