diff options
| author | phosphorus <steepout@qq.com> | 2019-08-19 00:34:02 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-19 00:34:02 -0500 |
| commit | 92f08b78a12ff119af853cb2bf58468208ea6a90 (patch) | |
| tree | b4636f43c056de11dd69130ce47039343a9f52c5 /src/libstd/sys_common/gnu | |
| parent | 963184bbb670c1ffa97fc28a98cd5e8473118859 (diff) | |
| parent | a807902dd6b4222179776c3f3c33da8dafdd4da1 (diff) | |
| download | rust-92f08b78a12ff119af853cb2bf58468208ea6a90.tar.gz rust-92f08b78a12ff119af853cb2bf58468208ea6a90.zip | |
Merge pull request #1 from rust-lang/master
Pull from newest repo
Diffstat (limited to 'src/libstd/sys_common/gnu')
| -rw-r--r-- | src/libstd/sys_common/gnu/libbacktrace.rs | 175 | ||||
| -rw-r--r-- | src/libstd/sys_common/gnu/mod.rs | 5 |
2 files changed, 0 insertions, 180 deletions
diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs deleted file mode 100644 index 6cd050242dd..00000000000 --- a/src/libstd/sys_common/gnu/libbacktrace.rs +++ /dev/null @@ -1,175 +0,0 @@ -use backtrace_sys::backtrace_state; - -use crate::ffi::CStr; -use crate::io; -use crate::mem; -use crate::ptr; -use crate::sys::backtrace::BacktraceContext; -use crate::sys_common::backtrace::Frame; - -pub fn foreach_symbol_fileline<F>(frame: Frame, - mut f: F, - _: &BacktraceContext) -> io::Result<bool> -where F: FnMut(&[u8], u32) -> io::Result<()> -{ - // pcinfo may return an arbitrary number of file:line pairs, - // in the order of stack trace (i.e., inlined calls first). - // in order to avoid allocation, we stack-allocate a fixed size of entries. - const FILELINE_SIZE: usize = 32; - let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE]; - let ret; - let fileline_count = { - let state = unsafe { init_state() }; - if state.is_null() { - return Err(io::Error::new( - io::ErrorKind::Other, - "failed to allocate libbacktrace state") - ) - } - let mut fileline_win: &mut [FileLine] = &mut fileline_buf; - let fileline_addr = &mut fileline_win as *mut &mut [FileLine]; - ret = unsafe { - backtrace_sys::backtrace_pcinfo( - state, - frame.exact_position as libc::uintptr_t, - pcinfo_cb, - error_cb, - fileline_addr as *mut libc::c_void, - ) - }; - FILELINE_SIZE - fileline_win.len() - }; - if ret == 0 { - for &(file, line) in &fileline_buf[..fileline_count] { - if file.is_null() { continue; } // just to be sure - let file = unsafe { CStr::from_ptr(file).to_bytes() }; - f(file, line)?; - } - Ok(fileline_count == FILELINE_SIZE) - } else { - Ok(false) - } -} - -/// Converts a pointer to symbol to its string value. -pub fn resolve_symname<F>(frame: Frame, - callback: F, - _: &BacktraceContext) -> io::Result<()> - where F: FnOnce(Option<&str>) -> io::Result<()> -{ - let symname = { - let state = unsafe { init_state() }; - if state.is_null() { - return Err(io::Error::new( - io::ErrorKind::Other, - "failed to allocate libbacktrace state") - ) - } - let mut data: *const libc::c_char = ptr::null(); - let data_addr = &mut data as *mut *const libc::c_char; - let ret = unsafe { - backtrace_sys::backtrace_syminfo( - state, - frame.symbol_addr as libc::uintptr_t, - syminfo_cb, - error_cb, - data_addr as *mut libc::c_void, - ) - }; - if ret == 0 || data.is_null() { - None - } else { - unsafe { - CStr::from_ptr(data).to_str().ok() - } - } - }; - callback(symname) -} - -//////////////////////////////////////////////////////////////////////// -// helper callbacks -//////////////////////////////////////////////////////////////////////// - -type FileLine = (*const libc::c_char, u32); - -extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char, - _errnum: libc::c_int) { - // do nothing for now -} -extern fn syminfo_cb(data: *mut libc::c_void, - _pc: libc::uintptr_t, - symname: *const libc::c_char, - _symval: libc::uintptr_t, - _symsize: libc::uintptr_t) { - let slot = data as *mut *const libc::c_char; - unsafe { *slot = symname; } -} -extern fn pcinfo_cb(data: *mut libc::c_void, - _pc: libc::uintptr_t, - filename: *const libc::c_char, - lineno: libc::c_int, - _function: *const libc::c_char) -> libc::c_int { - if !filename.is_null() { - let slot = data as *mut &mut [FileLine]; - let buffer = unsafe {ptr::read(slot)}; - - // if the buffer is not full, add file:line to the buffer - // and adjust the buffer for next possible calls to pcinfo_cb. - if !buffer.is_empty() { - buffer[0] = (filename, lineno as u32); - unsafe { ptr::write(slot, &mut buffer[1..]); } - } - } - - 0 -} - -// The libbacktrace API supports creating a state, but it does not -// support destroying a state. I personally take this to mean that a -// state is meant to be created and then live forever. -// -// I would love to register an at_exit() handler which cleans up this -// state, but libbacktrace provides no way to do so. -// -// With these constraints, this function has a statically cached state -// that is calculated the first time this is requested. Remember that -// backtracing all happens serially (one global lock). -// -// Things don't work so well on not-Linux since libbacktrace can't track -// down that executable this is. We at one point used env::current_exe but -// it turns out that there are some serious security issues with that -// approach. -// -// Specifically, on certain platforms like BSDs, a malicious actor can cause -// an arbitrary file to be placed at the path returned by current_exe. -// libbacktrace does not behave defensively in the presence of ill-formed -// DWARF information, and has been demonstrated to segfault in at least one -// case. There is no evidence at the moment to suggest that a more carefully -// constructed file can't cause arbitrary code execution. As a result of all -// of this, we don't hint libbacktrace with the path to the current process. -unsafe fn init_state() -> *mut backtrace_state { - static mut STATE: *mut backtrace_state = ptr::null_mut(); - if !STATE.is_null() { return STATE } - - let filename = match crate::sys::backtrace::gnu::get_executable_filename() { - Ok((filename, file)) => { - // filename is purposely leaked here since libbacktrace requires - // it to stay allocated permanently, file is also leaked so that - // the file stays locked - let filename_ptr = filename.as_ptr(); - mem::forget(filename); - mem::forget(file); - filename_ptr - }, - Err(_) => ptr::null(), - }; - - STATE = backtrace_sys::backtrace_create_state( - filename, - 0, - error_cb, - ptr::null_mut(), - ); - STATE -} diff --git a/src/libstd/sys_common/gnu/mod.rs b/src/libstd/sys_common/gnu/mod.rs deleted file mode 100644 index d6959697f2a..00000000000 --- a/src/libstd/sys_common/gnu/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] - -pub mod libbacktrace; |
