3
3
// ignore-aarch64
4
4
// ignore-mips
5
5
// ignore-mips64
6
- // ignore-powerpc
7
- // ignore-s390x
8
6
// ignore-sparc
9
7
// ignore-sparc64
10
8
// ignore-wasm
@@ -27,8 +25,9 @@ fn main() {
27
25
let args = env:: args ( ) . skip ( 1 ) . collect :: < Vec < _ > > ( ) ;
28
26
if args. len ( ) > 0 {
29
27
match & args[ 0 ] [ ..] {
30
- "main-thread" => recurse ( & MaybeUninit :: uninit ( ) ) ,
31
- "child-thread" => thread:: spawn ( || recurse ( & MaybeUninit :: uninit ( ) ) ) . join ( ) . unwrap ( ) ,
28
+ "main-recurse" => overflow_recurse ( ) ,
29
+ "child-recurse" => thread:: spawn ( overflow_recurse) . join ( ) . unwrap ( ) ,
30
+ "child-frame" => overflow_frame ( ) ,
32
31
_ => panic ! ( ) ,
33
32
}
34
33
return ;
@@ -41,9 +40,10 @@ fn main() {
41
40
// that we report stack overflow on the main thread, see #43052 for some
42
41
// details
43
42
if cfg ! ( not( target_os = "linux" ) ) {
44
- assert_overflow ( Command :: new ( & me) . arg ( "main-thread " ) ) ;
43
+ assert_overflow ( Command :: new ( & me) . arg ( "main-recurse " ) ) ;
45
44
}
46
- assert_overflow ( Command :: new ( & me) . arg ( "child-thread" ) ) ;
45
+ assert_overflow ( Command :: new ( & me) . arg ( "child-recurse" ) ) ;
46
+ assert_overflow ( Command :: new ( & me) . arg ( "child-frame" ) ) ;
47
47
}
48
48
49
49
#[ allow( unconditional_recursion) ]
@@ -55,6 +55,23 @@ fn recurse(array: &MaybeUninit<[u64; 1024]>) {
55
55
recurse ( & local) ;
56
56
}
57
57
58
+ #[ inline( never) ]
59
+ fn overflow_recurse ( ) {
60
+ recurse ( & MaybeUninit :: uninit ( ) ) ;
61
+ }
62
+
63
+ fn overflow_frame ( ) {
64
+ // By using a 1MiB stack frame with only 512KiB stack, we'll jump over any
65
+ // guard page, even with 64K pages -- but stack probes should catch it.
66
+ const STACK_SIZE : usize = 512 * 1024 ;
67
+ thread:: Builder :: new ( ) . stack_size ( STACK_SIZE ) . spawn ( || {
68
+ let local: MaybeUninit < [ u8 ; 2 * STACK_SIZE ] > = MaybeUninit :: uninit ( ) ;
69
+ unsafe {
70
+ black_box ( local. as_ptr ( ) as u64 ) ;
71
+ }
72
+ } ) . unwrap ( ) . join ( ) . unwrap ( ) ;
73
+ }
74
+
58
75
fn assert_overflow ( cmd : & mut Command ) {
59
76
let output = cmd. output ( ) . unwrap ( ) ;
60
77
assert ! ( !output. status. success( ) ) ;
0 commit comments