@@ -213,7 +213,7 @@ impl Drop for Thread {
213
213
}
214
214
215
215
#[ cfg( all(
216
- not( all ( target_os = "linux" , not ( target_env = "musl" ) ) ) ,
216
+ not( target_os = "linux" ) ,
217
217
not( target_os = "freebsd" ) ,
218
218
not( target_os = "macos" ) ,
219
219
not( all( target_os = "netbsd" , not( target_vendor = "rumprun" ) ) ) ,
@@ -233,7 +233,7 @@ pub mod guard {
233
233
}
234
234
235
235
#[ cfg( any(
236
- all ( target_os = "linux" , not ( target_env = "musl" ) ) ,
236
+ target_os = "linux" ,
237
237
target_os = "freebsd" ,
238
238
target_os = "macos" ,
239
239
all( target_os = "netbsd" , not( target_vendor = "rumprun" ) ) ,
@@ -333,9 +333,7 @@ pub mod guard {
333
333
let page_size = os:: page_size ( ) ;
334
334
PAGE_SIZE . store ( page_size, Ordering :: Relaxed ) ;
335
335
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" ) ) ) {
339
337
// Linux doesn't allocate the whole stack right away, and
340
338
// the kernel has its own stack-guard mechanism to fault
341
339
// when growing too close to an existing mapping. If we map
@@ -346,8 +344,15 @@ pub mod guard {
346
344
// Instead, we'll just note where we expect rlimit to start
347
345
// faulting, so our handler can report "stack overflow", and
348
346
// trust that the kernel's own stack guard will work.
347
+ let stackaddr = get_stack_start_aligned ( ) ?;
349
348
let stackaddr = stackaddr as usize ;
350
349
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
351
356
} else {
352
357
// Reallocate the last page of the stack.
353
358
// This ensures SIGBUS will be raised on
@@ -357,6 +362,7 @@ pub mod guard {
357
362
// than the initial mmap() used, so we mmap() here with
358
363
// read/write permissions and only then mprotect() it to
359
364
// no permissions at all. See issue #50313.
365
+ let stackaddr = get_stack_start_aligned ( ) ?;
360
366
let result = mmap (
361
367
stackaddr,
362
368
page_size,
@@ -406,7 +412,14 @@ pub mod guard {
406
412
let mut guardsize = 0 ;
407
413
assert_eq ! ( libc:: pthread_attr_getguardsize( & attr, & mut guardsize) , 0 ) ;
408
414
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
+ }
410
423
}
411
424
let mut stackaddr = crate :: ptr:: null_mut ( ) ;
412
425
let mut size = 0 ;
@@ -419,6 +432,8 @@ pub mod guard {
419
432
Some ( guardaddr - PAGE_SIZE . load ( Ordering :: Relaxed ) ..guardaddr)
420
433
} else if cfg ! ( target_os = "netbsd" ) {
421
434
Some ( stackaddr - guardsize..stackaddr)
435
+ } else if cfg ! ( all( target_os = "linux" , target_env = "musl" ) ) {
436
+ Some ( stackaddr - guardsize..stackaddr)
422
437
} else if cfg ! ( all( target_os = "linux" , target_env = "gnu" ) ) {
423
438
// glibc used to include the guard area within the stack, as noted in the BUGS
424
439
// section of `man pthread_attr_getguardsize`. This has been corrected starting
0 commit comments