@@ -69,40 +69,42 @@ impl SadnessFlavor {
6969 ///
7070 /// This is not safe. It intentionally crashes.
7171 pub unsafe fn make_sad ( self ) -> ! {
72- match self {
73- Self :: Abort => raise_abort ( ) ,
74- Self :: Segfault => raise_segfault ( ) ,
75- Self :: DivideByZero => raise_floating_point_exception ( ) ,
76- Self :: Illegal => raise_illegal_instruction ( ) ,
77- #[ cfg( unix) ]
78- Self :: Bus => raise_bus ( ) ,
79- Self :: Trap => raise_trap ( ) ,
80- #[ allow( unused_variables) ]
81- Self :: StackOverflow {
82- non_rust_thread,
83- long_jumps,
84- } => {
85- if !non_rust_thread {
86- raise_stack_overflow ( )
87- } else {
88- #[ cfg( unix) ]
89- {
90- raise_stack_overflow_in_non_rust_thread ( long_jumps)
91- }
92- #[ cfg( windows) ]
93- {
72+ unsafe {
73+ match self {
74+ Self :: Abort => raise_abort ( ) ,
75+ Self :: Segfault => raise_segfault ( ) ,
76+ Self :: DivideByZero => raise_floating_point_exception ( ) ,
77+ Self :: Illegal => raise_illegal_instruction ( ) ,
78+ #[ cfg( unix) ]
79+ Self :: Bus => raise_bus ( ) ,
80+ Self :: Trap => raise_trap ( ) ,
81+ #[ allow( unused_variables) ]
82+ Self :: StackOverflow {
83+ non_rust_thread,
84+ long_jumps,
85+ } => {
86+ if !non_rust_thread {
9487 raise_stack_overflow ( )
88+ } else {
89+ #[ cfg( unix) ]
90+ {
91+ raise_stack_overflow_in_non_rust_thread ( long_jumps)
92+ }
93+ #[ cfg( windows) ]
94+ {
95+ raise_stack_overflow ( )
96+ }
9597 }
9698 }
99+ #[ cfg( windows) ]
100+ Self :: Purecall => raise_purecall ( ) ,
101+ #[ cfg( windows) ]
102+ Self :: InvalidParameter => raise_invalid_parameter ( ) ,
103+ #[ cfg( windows) ]
104+ Self :: HeapCorruption => raise_heap_corruption ( ) ,
105+ #[ cfg( target_os = "macos" ) ]
106+ Self :: Guard => raise_guard_exception ( ) ,
97107 }
98- #[ cfg( windows) ]
99- Self :: Purecall => raise_purecall ( ) ,
100- #[ cfg( windows) ]
101- Self :: InvalidParameter => raise_invalid_parameter ( ) ,
102- #[ cfg( windows) ]
103- Self :: HeapCorruption => raise_heap_corruption ( ) ,
104- #[ cfg( target_os = "macos" ) ]
105- Self :: Guard => raise_guard_exception ( ) ,
106108 }
107109 }
108110}
@@ -113,7 +115,7 @@ impl SadnessFlavor {
113115///
114116/// This is not safe. It intentionally emits `SIGABRT`.
115117pub unsafe fn raise_abort ( ) -> ! {
116- libc:: abort ( )
118+ unsafe { libc:: abort ( ) }
117119}
118120
119121/// This is the fixed address used to generate a segfault. It's possible that
@@ -131,7 +133,7 @@ pub const SEGFAULT_ADDRESS: u32 = 0x42;
131133/// This is not safe. It intentionally crashes.
132134pub unsafe fn raise_segfault ( ) -> ! {
133135 let bad_ptr: * mut u8 = SEGFAULT_ADDRESS as _ ;
134- std:: ptr:: write_volatile ( bad_ptr, 1 ) ;
136+ unsafe { std:: ptr:: write_volatile ( bad_ptr, 1 ) } ;
135137
136138 // If we actually get here that means the address is mapped and writable
137139 // by the current process which is...unexpected
@@ -144,7 +146,7 @@ pub unsafe fn raise_segfault() -> ! {
144146///
145147/// This is not safe. It intentionally crashes.
146148pub unsafe fn raise_floating_point_exception ( ) -> ! {
147- let ohno = {
149+ let ohno = unsafe {
148150 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
149151 {
150152 let mut divisor: u32 ;
@@ -177,10 +179,12 @@ pub unsafe fn raise_floating_point_exception() -> ! {
177179///
178180/// This is not safe. It intentionally crashes.
179181pub unsafe fn raise_illegal_instruction ( ) -> ! {
180- #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
181- asm ! ( "ud2" ) ;
182- #[ cfg( any( target_arch = "arm" , target_arch = "aarch64" ) ) ]
183- asm ! ( "udf #0" ) ;
182+ unsafe {
183+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
184+ asm ! ( "ud2" ) ;
185+ #[ cfg( any( target_arch = "arm" , target_arch = "aarch64" ) ) ]
186+ asm ! ( "udf #0" ) ;
187+ }
184188
185189 std:: process:: abort ( )
186190}
@@ -195,35 +199,37 @@ pub unsafe fn raise_bus() -> ! {
195199 let mut temp_name = [ 0 ; 14 ] ;
196200 temp_name. copy_from_slice ( b"sigbus.XXXXXX\0 " ) ;
197201
198- let bus_fd = libc:: mkstemp ( temp_name. as_mut_ptr ( ) . cast ( ) ) ;
199- assert ! ( bus_fd != -1 ) ;
200-
201- let page_size = libc:: sysconf ( libc:: _SC_PAGESIZE) as usize ;
202-
203- let mapping = std:: slice:: from_raw_parts_mut (
204- libc:: mmap (
205- std:: ptr:: null_mut ( ) ,
206- 128 ,
207- libc:: PROT_READ | libc:: PROT_WRITE ,
208- libc:: MAP_SHARED ,
209- bus_fd,
210- 0 ,
211- )
212- . cast :: < u8 > ( ) ,
213- page_size + page_size / 2 ,
214- ) ;
215-
216- libc:: unlink ( temp_name. as_ptr ( ) . cast ( ) ) ;
202+ unsafe {
203+ let bus_fd = libc:: mkstemp ( temp_name. as_mut_ptr ( ) . cast ( ) ) ;
204+ assert ! ( bus_fd != -1 ) ;
205+
206+ let page_size = libc:: sysconf ( libc:: _SC_PAGESIZE) as usize ;
207+
208+ let mapping = std:: slice:: from_raw_parts_mut (
209+ libc:: mmap (
210+ std:: ptr:: null_mut ( ) ,
211+ 128 ,
212+ libc:: PROT_READ | libc:: PROT_WRITE ,
213+ libc:: MAP_SHARED ,
214+ bus_fd,
215+ 0 ,
216+ )
217+ . cast :: < u8 > ( ) ,
218+ page_size + page_size / 2 ,
219+ ) ;
217220
218- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html
219- // The system shall always zero-fill any partial page at the end of
220- // an object. Further, the system shall never write out any modified
221- // portions of the last page of an object which are beyond its end.
222- // References within the address range starting at pa and continuing
223- // for len bytes to whole pages following the end of an object shall
224- // result in delivery of a SIGBUS signal.
225- mapping[ 20 ] = 20 ;
226- println ! ( "{}" , mapping[ 20 ] ) ;
221+ libc:: unlink ( temp_name. as_ptr ( ) . cast ( ) ) ;
222+
223+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html
224+ // The system shall always zero-fill any partial page at the end of
225+ // an object. Further, the system shall never write out any modified
226+ // portions of the last page of an object which are beyond its end.
227+ // References within the address range starting at pa and continuing
228+ // for len bytes to whole pages following the end of an object shall
229+ // result in delivery of a SIGBUS signal.
230+ mapping[ 20 ] = 20 ;
231+ println ! ( "{}" , mapping[ 20 ] ) ;
232+ }
227233
228234 std:: process:: abort ( )
229235}
@@ -234,12 +240,14 @@ pub unsafe fn raise_bus() -> ! {
234240///
235241/// This is not safe. It intentionally crashes.
236242pub unsafe fn raise_trap ( ) -> ! {
237- #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
238- asm ! ( "int3" ) ;
239- #[ cfg( target_arch = "arm" ) ]
240- asm ! ( ".inst 0xe7f001f0" ) ;
241- #[ cfg( target_arch = "aarch64" ) ]
242- asm ! ( ".inst 0xd4200000" ) ;
243+ unsafe {
244+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
245+ asm ! ( "int3" ) ;
246+ #[ cfg( target_arch = "arm" ) ]
247+ asm ! ( ".inst 0xe7f001f0" ) ;
248+ #[ cfg( target_arch = "aarch64" ) ]
249+ asm ! ( ".inst 0xd4200000" ) ;
250+ }
243251
244252 std:: process:: abort ( )
245253}
@@ -281,68 +289,71 @@ pub unsafe fn raise_stack_overflow() -> ! {
281289/// This is not safe. It intentionally crashes.
282290#[ cfg( unix) ]
283291pub unsafe fn raise_stack_overflow_in_non_rust_thread ( uses_longjmp : bool ) -> ! {
284- let mut native: libc:: pthread_t = std:: mem:: zeroed ( ) ;
285- let mut attr: libc:: pthread_attr_t = std:: mem:: zeroed ( ) ;
286-
287- assert_eq ! (
288- libc:: pthread_attr_setstacksize( & mut attr, 2 * 1024 * 1024 ) ,
289- 0 ,
290- "failed to set thread stack size" ,
291- ) ;
292+ unsafe {
293+ let mut native: libc:: pthread_t = std:: mem:: zeroed ( ) ;
294+ let mut attr: libc:: pthread_attr_t = std:: mem:: zeroed ( ) ;
292295
293- use std:: sync;
296+ assert_eq ! (
297+ libc:: pthread_attr_setstacksize( & mut attr, 2 * 1024 * 1024 ) ,
298+ 0 ,
299+ "failed to set thread stack size" ,
300+ ) ;
294301
295- let pair = sync:: Arc :: new ( ( sync:: Mutex :: new ( false ) , sync:: Condvar :: new ( ) ) ) ;
296- let tpair = pair. clone ( ) ;
302+ use std:: sync;
297303
298- extern "C" fn thread_start ( arg : * mut libc:: c_void ) -> * mut libc:: c_void {
299- {
300- let tpair =
301- unsafe { sync:: Arc :: from_raw ( arg as * const ( sync:: Mutex < bool > , sync:: Condvar ) ) } ;
302- let ( lock, cvar) = & * tpair;
303- let mut started = lock. lock ( ) . unwrap ( ) ;
304- * started = true ;
305- cvar. notify_one ( ) ;
306- }
304+ let pair = sync:: Arc :: new ( ( sync:: Mutex :: new ( false ) , sync:: Condvar :: new ( ) ) ) ;
305+ let tpair = pair. clone ( ) ;
307306
308- unsafe { raise_stack_overflow ( ) } ;
309- }
307+ extern "C" fn thread_start ( arg : * mut libc:: c_void ) -> * mut libc:: c_void {
308+ {
309+ let tpair = unsafe {
310+ sync:: Arc :: from_raw ( arg as * const ( sync:: Mutex < bool > , sync:: Condvar ) )
311+ } ;
312+ let ( lock, cvar) = & * tpair;
313+ let mut started = lock. lock ( ) . unwrap ( ) ;
314+ * started = true ;
315+ cvar. notify_one ( ) ;
316+ }
310317
311- let ret = libc:: pthread_create (
312- & mut native,
313- & attr,
314- thread_start,
315- sync:: Arc :: into_raw ( tpair) as * mut _ ,
316- ) ;
318+ unsafe { raise_stack_overflow ( ) } ;
319+ }
317320
318- // We might not get here, but that's ok
319- assert_eq ! (
320- libc:: pthread_attr_destroy( & mut attr) ,
321- 0 ,
322- "failed to destroy thread attributes"
323- ) ;
324- assert_eq ! ( ret, 0 , "pthread_create failed" ) ;
321+ let ret = libc:: pthread_create (
322+ & mut native,
323+ & attr,
324+ thread_start,
325+ sync:: Arc :: into_raw ( tpair) as * mut _ ,
326+ ) ;
325327
326- // Note if we're doing longjmp shenanigans, we can't do thread join, that
327- // has to be handled by the calling code
328- if !uses_longjmp {
328+ // We might not get here, but that's ok
329329 assert_eq ! (
330- libc:: pthread_join ( native , std :: ptr :: null_mut ( ) ) ,
330+ libc:: pthread_attr_destroy ( & mut attr ) ,
331331 0 ,
332- "failed to join "
332+ "failed to destroy thread attributes "
333333 ) ;
334- }
334+ assert_eq ! ( ret, 0 , "pthread_create failed" ) ;
335+
336+ // Note if we're doing longjmp shenanigans, we can't do thread join, that
337+ // has to be handled by the calling code
338+ if !uses_longjmp {
339+ assert_eq ! (
340+ libc:: pthread_join( native, std:: ptr:: null_mut( ) ) ,
341+ 0 ,
342+ "failed to join"
343+ ) ;
344+ }
335345
336- let ( lock, cvar) = & * pair;
337- let mut started = lock. lock ( ) . unwrap ( ) ;
338- while !* started {
339- started = cvar. wait ( started) . unwrap ( ) ;
340- }
346+ let ( lock, cvar) = & * pair;
347+ let mut started = lock. lock ( ) . unwrap ( ) ;
348+ while !* started {
349+ started = cvar. wait ( started) . unwrap ( ) ;
350+ }
341351
342- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
352+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
343353
344- #[ allow( clippy:: empty_loop) ]
345- loop { }
354+ #[ allow( clippy:: empty_loop) ]
355+ loop { }
356+ }
346357}
347358
348359/// [`SadnessFlavor::StackOverflow`]
@@ -353,7 +364,7 @@ pub unsafe fn raise_stack_overflow_in_non_rust_thread(uses_longjmp: bool) -> ! {
353364#[ inline]
354365#[ cfg( unix) ]
355366pub unsafe fn raise_stack_overflow_in_non_rust_thread_normal ( ) -> ! {
356- raise_stack_overflow_in_non_rust_thread ( false )
367+ unsafe { raise_stack_overflow_in_non_rust_thread ( false ) }
357368}
358369
359370/// [`SadnessFlavor::StackOverflow`]
@@ -364,7 +375,7 @@ pub unsafe fn raise_stack_overflow_in_non_rust_thread_normal() -> ! {
364375#[ inline]
365376#[ cfg( unix) ]
366377pub unsafe fn raise_stack_overflow_in_non_rust_thread_longjmp ( ) -> ! {
367- raise_stack_overflow_in_non_rust_thread ( true )
378+ unsafe { raise_stack_overflow_in_non_rust_thread ( true ) }
368379}
369380
370381/// [`SadnessFlavor::Purecall`]
0 commit comments