@@ -213,7 +213,7 @@ impl Drop for Thread {
213213}
214214
215215#[ cfg( all(
216- not( all ( target_os = "linux" , not ( target_env = "musl" ) ) ) ,
216+ not( target_os = "linux" ) ,
217217 not( target_os = "freebsd" ) ,
218218 not( target_os = "macos" ) ,
219219 not( all( target_os = "netbsd" , not( target_vendor = "rumprun" ) ) ) ,
@@ -233,7 +233,7 @@ pub mod guard {
233233}
234234
235235#[ cfg( any(
236- all ( target_os = "linux" , not ( target_env = "musl" ) ) ,
236+ target_os = "linux" ,
237237 target_os = "freebsd" ,
238238 target_os = "macos" ,
239239 all( target_os = "netbsd" , not( target_vendor = "rumprun" ) ) ,
@@ -333,9 +333,7 @@ pub mod guard {
333333 let page_size = os:: page_size ( ) ;
334334 PAGE_SIZE . store ( page_size, Ordering :: Relaxed ) ;
335335
336- let stackaddr = get_stack_start_aligned ( ) ?;
337-
338- if cfg ! ( target_os = "linux" ) {
336+ if cfg ! ( all( target_os = "linux" , not( target_env = "musl" ) ) ) {
339337 // Linux doesn't allocate the whole stack right away, and
340338 // the kernel has its own stack-guard mechanism to fault
341339 // when growing too close to an existing mapping. If we map
@@ -346,8 +344,15 @@ pub mod guard {
346344 // Instead, we'll just note where we expect rlimit to start
347345 // faulting, so our handler can report "stack overflow", and
348346 // trust that the kernel's own stack guard will work.
347+ let stackaddr = get_stack_start_aligned ( ) ?;
349348 let stackaddr = stackaddr as usize ;
350349 Some ( stackaddr - page_size..stackaddr)
350+ } else if cfg ! ( all( target_os = "linux" , target_env = "musl" ) ) {
351+ // For the main thread, the musl's pthread_attr_getstack
352+ // returns the current stack size, rather than maximum size
353+ // it can eventually grow to. It cannot be used to determine
354+ // the position of kernel's stack guard.
355+ None
351356 } else {
352357 // Reallocate the last page of the stack.
353358 // This ensures SIGBUS will be raised on
@@ -357,6 +362,7 @@ pub mod guard {
357362 // than the initial mmap() used, so we mmap() here with
358363 // read/write permissions and only then mprotect() it to
359364 // no permissions at all. See issue #50313.
365+ let stackaddr = get_stack_start_aligned ( ) ?;
360366 let result = mmap (
361367 stackaddr,
362368 page_size,
@@ -406,7 +412,14 @@ pub mod guard {
406412 let mut guardsize = 0 ;
407413 assert_eq ! ( libc:: pthread_attr_getguardsize( & attr, & mut guardsize) , 0 ) ;
408414 if guardsize == 0 {
409- panic ! ( "there is no guard page" ) ;
415+ if cfg ! ( all( target_os = "linux" , target_env = "musl" ) ) {
416+ // musl versions before 1.1.19 always reported guard
417+ // size obtained from pthread_attr_get_np as zero.
418+ // Use page size as a fallback.
419+ guardsize = PAGE_SIZE . load ( Ordering :: Relaxed ) ;
420+ } else {
421+ panic ! ( "there is no guard page" ) ;
422+ }
410423 }
411424 let mut stackaddr = crate :: ptr:: null_mut ( ) ;
412425 let mut size = 0 ;
@@ -419,6 +432,8 @@ pub mod guard {
419432 Some ( guardaddr - PAGE_SIZE . load ( Ordering :: Relaxed ) ..guardaddr)
420433 } else if cfg ! ( target_os = "netbsd" ) {
421434 Some ( stackaddr - guardsize..stackaddr)
435+ } else if cfg ! ( all( target_os = "linux" , target_env = "musl" ) ) {
436+ Some ( stackaddr - guardsize..stackaddr)
422437 } else if cfg ! ( all( target_os = "linux" , target_env = "gnu" ) ) {
423438 // glibc used to include the guard area within the stack, as noted in the BUGS
424439 // section of `man pthread_attr_getguardsize`. This has been corrected starting
0 commit comments