u-skip-main-thread-stack-guard
authorRust Maintainers <pkg-rust-maintainers@lists.alioth.debian.org>
Wed, 9 Aug 2017 02:49:55 +0000 (03:49 +0100)
committerPeter Michael Green <plugwash@raspbian.org>
Wed, 9 Aug 2017 02:49:55 +0000 (03:49 +0100)
commit be509b3387aebb453b09a4942cf902c7d05a0f1e
Author: Josh Stone <jistone@redhat.com>
Date:   Wed Jul 5 12:03:17 2017 -0700

    Skip the main thread's manual stack guard on Linux

    Linux doesn't allocate the whole stack right away, and the kernel has
    its own stack-guard mechanism to fault when growing too close to an
    existing mapping.  If we map our own guard, then the kernel starts
    enforcing a rather large gap above that, rendering much of the possible
    stack space useless.

    Instead, we'll just note where we expect rlimit to start faulting, so
    our handler can report "stack overflow", and trust that the kernel's own
    stack guard will work.

    Fixes #43052.

Gbp-Pq: Name u-skip-main-thread-stack-guard.patch

src/libstd/sys/unix/thread.rs

index 1642baa34d636ca65b9877eceba69d1967c2a330..15747746611c9dd72efac438e8b52fe5c96869b5 100644 (file)
@@ -264,23 +264,37 @@ pub mod guard {
                 as *mut libc::c_void;
         }
 
-        // Rellocate the last page of the stack.
-        // This ensures SIGBUS will be raised on
-        // stack overflow.
-        let result = mmap(stackaddr, psize, PROT_NONE,
-                          MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
-
-        if result != stackaddr || result == MAP_FAILED {
-            panic!("failed to allocate a guard page");
-        }
-
-        let offset = if cfg!(any(target_os = "linux", target_os = "freebsd")) {
-            2
+        if cfg!(target_os = "linux") {
+            // Linux doesn't allocate the whole stack right away, and
+            // the kernel has its own stack-guard mechanism to fault
+            // when growing too close to an existing mapping.  If we map
+            // our own guard, then the kernel starts enforcing a rather
+            // large gap above that, rendering much of the possible
+            // stack space useless.  See #43052.
+            //
+            // Instead, we'll just note where we expect rlimit to start
+            // faulting, so our handler can report "stack overflow", and
+            // trust that the kernel's own stack guard will work.
+            Some(stackaddr as usize)
         } else {
-            1
-        };
+            // Reallocate the last page of the stack.
+            // This ensures SIGBUS will be raised on
+            // stack overflow.
+            let result = mmap(stackaddr, psize, PROT_NONE,
+                              MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
+
+            if result != stackaddr || result == MAP_FAILED {
+                panic!("failed to allocate a guard page");
+            }
 
-        Some(stackaddr as usize + offset * psize)
+            let offset = if cfg!(target_os = "freebsd") {
+                2
+            } else {
+                1
+            };
+
+            Some(stackaddr as usize + offset * psize)
+        }
     }
 
     #[cfg(target_os = "solaris")]