unix: lift init of sigaltstack before sigaction · patricklam/verify-rust-std@33a32f2

@@ -123,28 +123,36 @@ mod imp {

123123

static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());

124124

static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);

125125126+

/// # Safety

127+

/// Must be called only once

128+

#[forbid(unsafe_op_in_unsafe_fn)]

126129

pub unsafe fn init() {

127130

PAGE_SIZE.store(os::page_size(), Ordering::Relaxed);

128131129132

// Always write to GUARD to ensure the TLS variable is allocated.

130-

let guard = install_main_guard().unwrap_or(0..0);

133+

let guard = unsafe { install_main_guard().unwrap_or(0..0) };

131134

GUARD.set((guard.start, guard.end));

132135133-

let mut action: sigaction = mem::zeroed();

136+

// SAFETY: assuming all platforms define struct sigaction as "zero-initializable"

137+

let mut action: sigaction = unsafe { mem::zeroed() };

134138

for &signal in &[SIGSEGV, SIGBUS] {

135-

sigaction(signal, ptr::null_mut(), &mut action);

139+

// SAFETY: just fetches the current signal handler into action

140+

unsafe { sigaction(signal, ptr::null_mut(), &mut action) };

136141

// Configure our signal handler if one is not already set.

137142

if action.sa_sigaction == SIG_DFL {

143+

if !NEED_ALTSTACK.load(Ordering::Relaxed) {

144+

// haven't set up our sigaltstack yet

145+

NEED_ALTSTACK.store(true, Ordering::Release);

146+

let handler = unsafe { make_handler(true) };

147+

MAIN_ALTSTACK.store(handler.data, Ordering::Relaxed);

148+

mem::forget(handler);

149+

}

138150

action.sa_flags = SA_SIGINFO | SA_ONSTACK;

139151

action.sa_sigaction = signal_handler as sighandler_t;

140-

sigaction(signal, &action, ptr::null_mut());

141-

NEED_ALTSTACK.store(true, Ordering::Relaxed);

152+

// SAFETY: only overriding signals if the default is set

153+

unsafe { sigaction(signal, &action, ptr::null_mut()) };

142154

}

143155

}

144-145-

let handler = make_handler(true);

146-

MAIN_ALTSTACK.store(handler.data, Ordering::Relaxed);

147-

mem::forget(handler);

148156

}

149157150158

pub unsafe fn cleanup() {