Segfaults under Mac OS with multithreaded code


#1

Under the most recent stable Rust compiler (1.27.1), my multithreaded programs have been segfaulting on Mac OS for no obvious reason. Even a toy program like this one will trigger a segmentation fault:

use std::thread::sleep;
use std::time::Duration;

fn main() {
    use std::thread::spawn;
    use std::sync::{Arc, Mutex};

    let i = Arc::new(Mutex::new(0));
    let j = Arc::clone(&i);

    spawn(move || {
        loop {
            sleep(Duration::from_secs(1));
            increment(&mut j.lock().unwrap());
        }
    });

    sleep(Duration::from_secs(10));

    println!("{}", i.lock().unwrap());
}

fn increment(i: &mut u32) {
    *i += 1;
}

and Mac OS’s console log displays the following:

Crashed Thread:        1

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       EXC_I386_GPFLT
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

Thread 0:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib        	0x00007fff977b6f46 __semwait_signal + 10
1   libsystem_c.dylib             	0x00007fff9773db72 nanosleep + 199
2   threadtest                    	0x00000001080b1c31 std::thread::sleep::h109ad7e5121aeaf6 + 145 (thread.rs:163)
3   threadtest                    	0x00000001080a3e58 threadtest::main::h9cba4ed514e66637 + 200 (main.rs:18)
4   threadtest                    	0x00000001080a31d2 std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h9782edd05e0ee6f0 + 18 (rt.rs:74)
5   threadtest                    	0x00000001080b7848 std::panicking::try::do_call::h189213549cc5f769 + 24 (panicking.rs:310)
6   threadtest                    	0x00000001080c352f __rust_maybe_catch_panic + 31 (lib.rs:113)
7   threadtest                    	0x00000001080af662 std::rt::lang_start_internal::ha7b18db3fc20d103 + 242 (panicking.rs:294)
8   threadtest                    	0x00000001080a31b2 std::rt::lang_start::h102615e28a6af2ec + 66 (rt.rs:74)
9   threadtest                    	0x00000001080a3ff5 main + 37
10  libdyld.dylib                 	0x00007fff97688235 start + 1

Thread 1 Crashed:
0   threadtest                    	0x00000001080b78a2 std::panicking::panicking::h01f4a398b1d2259a + 66 (panicking.rs:317)
1   threadtest                    	0x00000001080a13dd std::thread::panicking::hc6a048073601eb35 + 13 (mod.rs:650)
2   threadtest                    	0x00000001080a5301 std::sys_common::poison::Flag::borrow::h1c62dc888be789ac + 17 (poison.rs:36)
3   threadtest                    	0x00000001080a4567 _$LT$std..sync..mutex..MutexGuard$LT$$u27$mutex$C$$u20$T$GT$$GT$::new::h21bbafc21788f974 + 39 (mutex.rs:426)
4   threadtest                    	0x00000001080a4533 _$LT$std..sync..mutex..Mutex$LT$T$GT$$GT$::lock::he53d3463e986d885 + 51 (mutex.rs:233)
5   threadtest                    	0x00000001080a162c threadtest::main::_$u7b$$u7b$closure$u7d$$u7d$::h2650746525c653d5 + 108 (main.rs:14)
6   threadtest                    	0x00000001080a4905 std::sys_common::backtrace::__rust_begin_short_backtrace::hbee485460cfb9ecd + 21 (backtrace.rs:137)
7   threadtest                    	0x00000001080a1f4d std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h1595bfd4df87dd50 + 29 (mod.rs:410)
8   threadtest                    	0x00000001080a3ac5 _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h4a35b6e63caaa518 + 21 (panic.rs:306)
9   threadtest                    	0x00000001080a2ac2 std::panicking::try::do_call::h2a47023d3d3c6e39 + 50 (panicking.rs:310)
10  threadtest                    	0x00000001080c352f __rust_maybe_catch_panic + 31 (lib.rs:113)
11  threadtest                    	0x00000001080a2a0f std::panicking::try::hae57caa579b15fb4 + 63 (panicking.rs:289)
12  threadtest                    	0x00000001080a3ae5 std::panic::catch_unwind::hd674f79be856b365 + 21 (panic.rs:374)
13  threadtest                    	0x00000001080a1da0 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::hee48ec257a37a824 + 224 (mod.rs:408)
14  threadtest                    	0x00000001080a1f90 _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h0eb83bff9d14e645 + 48 (boxed.rs:638)
15  threadtest                    	0x00000001080b5718 std::sys_common::thread::start_thread::hf39c8bd91f08cd93 + 136 (thread.rs:25)
16  threadtest                    	0x00000001080ab009 std::sys::unix::thread::Thread::new::thread_start::h27c7af0fa85baf64 + 9 (thread.rs:92)
17  libsystem_pthread.dylib       	0x00007fff978a193b _pthread_body + 180
18  libsystem_pthread.dylib       	0x00007fff978a1887 _pthread_start + 286
19  libsystem_pthread.dylib       	0x00007fff978a108d thread_start + 13

Since the toy program works just fine on a Linux system, is there some problem with Rust’s compiler or is it a problem with my system? Any help would be appreciated!


#2

I have seen various incidents of seg faults on macOS due to a bug in an older version of X code in its handling of TLS. But, I don’t see any TLS in your stack trace unless I’m mistaken? What version of X code do you have?


#3

I have Xcode version 7.3. Oh, and I’m running under Mac OS 10.12.6.


#4

Looks like this was a bug in Rust’s compiler after all, as the crashes no longer occur on my MacOS box using version 1.28.