|
2 | 2 | //! Primarily used to extract a backtrace from stack overflow
|
3 | 3 |
|
4 | 4 | use std::alloc::{Layout, alloc};
|
5 |
| -use std::{fmt, mem, ptr}; |
| 5 | +use std::{fmt, mem, ptr, slice}; |
6 | 6 |
|
7 | 7 | use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE};
|
8 | 8 |
|
@@ -35,20 +35,22 @@ macro raw_errln($tokens:tt) {
|
35 | 35 | }
|
36 | 36 |
|
37 | 37 | /// Signal handler installed for SIGSEGV
|
38 |
| -// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint |
39 |
| -#[allow(static_mut_refs)] |
40 |
| -extern "C" fn print_stack_trace(_: libc::c_int) { |
| 38 | +/// |
| 39 | +/// # Safety |
| 40 | +/// |
| 41 | +/// Caller must ensure that this function is not re-entered. |
| 42 | +unsafe extern "C" fn print_stack_trace(_: libc::c_int) { |
41 | 43 | const MAX_FRAMES: usize = 256;
|
42 |
| - // Reserve data segment so we don't have to malloc in a signal handler, which might fail |
43 |
| - // in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking |
44 |
| - static mut STACK_TRACE: [*mut libc::c_void; MAX_FRAMES] = [ptr::null_mut(); MAX_FRAMES]; |
45 | 44 | let stack = unsafe {
|
| 45 | + // Reserve data segment so we don't have to malloc in a signal handler, which might fail |
| 46 | + // in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking |
| 47 | + static mut STACK_TRACE: [*mut libc::c_void; MAX_FRAMES] = [ptr::null_mut(); MAX_FRAMES]; |
46 | 48 | // Collect return addresses
|
47 |
| - let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), MAX_FRAMES as i32); |
| 49 | + let depth = libc::backtrace(&raw mut STACK_TRACE as _, MAX_FRAMES as i32); |
48 | 50 | if depth == 0 {
|
49 | 51 | return;
|
50 | 52 | }
|
51 |
| - &STACK_TRACE.as_slice()[0..(depth as _)] |
| 53 | + slice::from_raw_parts(&raw const STACK_TRACE as _, depth as _) |
52 | 54 | };
|
53 | 55 |
|
54 | 56 | // Just a stack trace is cryptic. Explain what we're doing.
|
|
0 commit comments