std: Avoid use of libc in portable modules

This commit removes usage of the `libc` crate in "portable" modules like
those at the top level and `sys_common`. Instead common types like `*mut
u8` or `u32` are used instead of `*mut c_void` or `c_int` as well as
switching to platform-specific functions like `sys::strlen` instead of
`libc::strlen`.
This commit is contained in:
Alex Crichton 2017-11-01 13:04:03 -07:00
parent 348930eb4e
commit 5c3fe111d4
16 changed files with 33 additions and 31 deletions

View file

@ -14,7 +14,6 @@ use cmp::Ordering;
use error::Error; use error::Error;
use fmt::{self, Write}; use fmt::{self, Write};
use io; use io;
use libc;
use mem; use mem;
use memchr; use memchr;
use ops; use ops;
@ -22,6 +21,7 @@ use os::raw::c_char;
use ptr; use ptr;
use slice; use slice;
use str::{self, Utf8Error}; use str::{self, Utf8Error};
use sys;
/// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the
/// middle. /// middle.
@ -404,7 +404,7 @@ impl CString {
/// ``` /// ```
#[stable(feature = "cstr_memory", since = "1.4.0")] #[stable(feature = "cstr_memory", since = "1.4.0")]
pub unsafe fn from_raw(ptr: *mut c_char) -> CString { pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
let len = libc::strlen(ptr) + 1; // Including the NUL byte let len = sys::strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts_mut(ptr, len as usize); let slice = slice::from_raw_parts_mut(ptr, len as usize);
CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) } CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
} }
@ -861,7 +861,7 @@ impl CStr {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr { pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
let len = libc::strlen(ptr); let len = sys::strlen(ptr);
let ptr = ptr as *const u8; let ptr = ptr as *const u8;
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1)) CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
} }

View file

@ -96,8 +96,8 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
if cx.idx < cx.frames.len() { if cx.idx < cx.frames.len() {
cx.frames[cx.idx] = Frame { cx.frames[cx.idx] = Frame {
symbol_addr: symaddr, symbol_addr: symaddr as *mut u8,
exact_position: ip, exact_position: ip as *mut u8,
}; };
cx.idx += 1; cx.idx += 1;
} }

View file

@ -12,6 +12,7 @@
use io::{self, ErrorKind}; use io::{self, ErrorKind};
pub use libc::strlen;
pub use self::rand::hashmap_random_keys; pub use self::rand::hashmap_random_keys;
pub mod args; pub mod args;

View file

@ -22,7 +22,7 @@ pub fn resolve_symname<F>(frame: Frame,
{ {
unsafe { unsafe {
let mut info: Dl_info = intrinsics::init(); let mut info: Dl_info = intrinsics::init();
let symname = if dladdr(frame.exact_position, &mut info) == 0 || let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 ||
info.dli_sname.is_null() { info.dli_sname.is_null() {
None None
} else { } else {
@ -41,6 +41,5 @@ struct Dl_info {
} }
extern { extern {
fn dladdr(addr: *const libc::c_void, fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
info: *mut Dl_info) -> libc::c_int;
} }

View file

@ -20,7 +20,7 @@ pub use self::dladdr::resolve_symname;
#[cfg(target_os = "emscripten")] #[cfg(target_os = "emscripten")]
pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool> pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
where where
F: FnMut(&[u8], ::libc::c_int) -> io::Result<()> F: FnMut(&[u8], u32) -> io::Result<()>
{ {
Ok(false) Ok(false)
} }

View file

@ -36,8 +36,8 @@ pub fn unwind_backtrace(frames: &mut [Frame])
} as usize; } as usize;
for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) { for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) {
*to = Frame { *to = Frame {
exact_position: *from, exact_position: *from as *mut u8,
symbol_addr: *from, symbol_addr: *from as *mut u8,
}; };
} }
Ok((nb_frames as usize, BacktraceContext)) Ok((nb_frames as usize, BacktraceContext))

View file

@ -96,8 +96,8 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
if cx.idx < cx.frames.len() { if cx.idx < cx.frames.len() {
cx.frames[cx.idx] = Frame { cx.frames[cx.idx] = Frame {
symbol_addr: symaddr, symbol_addr: symaddr as *mut u8,
exact_position: ip, exact_position: ip as *mut u8,
}; };
cx.idx += 1; cx.idx += 1;
} }

View file

@ -30,6 +30,7 @@ use libc;
#[cfg(all(not(dox), target_os = "l4re"))] pub use os::linux as platform; #[cfg(all(not(dox), target_os = "l4re"))] pub use os::linux as platform;
pub use self::rand::hashmap_random_keys; pub use self::rand::hashmap_random_keys;
pub use libc::strlen;
#[macro_use] #[macro_use]
pub mod weak; pub mod weak;

View file

@ -87,7 +87,7 @@ impl Thread {
}; };
extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void { extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
unsafe { start_thread(main); } unsafe { start_thread(main as *mut u8); }
ptr::null_mut() ptr::null_mut()
} }
} }

View file

@ -95,8 +95,8 @@ pub fn unwind_backtrace(frames: &mut [Frame])
frame.AddrReturn.Offset == 0 { break } frame.AddrReturn.Offset == 0 { break }
frames[i] = Frame { frames[i] = Frame {
symbol_addr: (addr - 1) as *const c_void, symbol_addr: (addr - 1) as *const u8,
exact_position: (addr - 1) as *const c_void, exact_position: (addr - 1) as *const u8,
}; };
i += 1; i += 1;
} }

View file

@ -10,7 +10,7 @@
use ffi::CStr; use ffi::CStr;
use io; use io;
use libc::{c_ulong, c_int, c_char}; use libc::{c_ulong, c_char};
use mem; use mem;
use sys::c; use sys::c;
use sys::backtrace::BacktraceContext; use sys::backtrace::BacktraceContext;
@ -59,7 +59,7 @@ pub fn foreach_symbol_fileline<F>(frame: Frame,
mut f: F, mut f: F,
context: &BacktraceContext) context: &BacktraceContext)
-> io::Result<bool> -> io::Result<bool>
where F: FnMut(&[u8], c_int) -> io::Result<()> where F: FnMut(&[u8], u32) -> io::Result<()>
{ {
let SymGetLineFromAddr64 = sym!(&context.dbghelp, let SymGetLineFromAddr64 = sym!(&context.dbghelp,
"SymGetLineFromAddr64", "SymGetLineFromAddr64",
@ -76,7 +76,7 @@ pub fn foreach_symbol_fileline<F>(frame: Frame,
&mut line); &mut line);
if ret == c::TRUE { if ret == c::TRUE {
let name = CStr::from_ptr(line.Filename).to_bytes(); let name = CStr::from_ptr(line.Filename).to_bytes();
f(name, line.LineNumber as c_int)?; f(name, line.LineNumber as u32)?;
} }
Ok(false) Ok(false)
} }

View file

@ -17,6 +17,7 @@ use os::windows::ffi::{OsStrExt, OsStringExt};
use path::PathBuf; use path::PathBuf;
use time::Duration; use time::Duration;
pub use libc::strlen;
pub use self::rand::hashmap_random_keys; pub use self::rand::hashmap_random_keys;
#[macro_use] pub mod compat; #[macro_use] pub mod compat;

View file

@ -52,7 +52,7 @@ impl Thread {
}; };
extern "system" fn thread_start(main: *mut c_void) -> c::DWORD { extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
unsafe { start_thread(main); } unsafe { start_thread(main as *mut u8); }
0 0
} }
} }

View file

@ -14,7 +14,6 @@
use env; use env;
use io::prelude::*; use io::prelude::*;
use io; use io;
use libc;
use str; use str;
use sync::atomic::{self, Ordering}; use sync::atomic::{self, Ordering};
use path::{self, Path}; use path::{self, Path};
@ -39,9 +38,9 @@ pub const HEX_WIDTH: usize = 10;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Frame { pub struct Frame {
/// Exact address of the call that failed. /// Exact address of the call that failed.
pub exact_position: *const libc::c_void, pub exact_position: *const u8,
/// Address of the enclosing function. /// Address of the enclosing function.
pub symbol_addr: *const libc::c_void, pub symbol_addr: *const u8,
} }
/// Max number of frames to print. /// Max number of frames to print.
@ -201,8 +200,10 @@ fn output(w: &mut Write, idx: usize, frame: Frame,
/// ///
/// See also `output`. /// See also `output`.
#[allow(dead_code)] #[allow(dead_code)]
fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int, fn output_fileline(w: &mut Write,
format: PrintFormat) -> io::Result<()> { file: &[u8],
line: u32,
format: PrintFormat) -> io::Result<()> {
// prior line: " ##: {:2$} - func" // prior line: " ##: {:2$} - func"
w.write_all(b"")?; w.write_all(b"")?;
match format { match format {

View file

@ -20,13 +20,13 @@ use sys_common::backtrace::Frame;
pub fn foreach_symbol_fileline<F>(frame: Frame, pub fn foreach_symbol_fileline<F>(frame: Frame,
mut f: F, mut f: F,
_: &BacktraceContext) -> io::Result<bool> _: &BacktraceContext) -> io::Result<bool>
where F: FnMut(&[u8], libc::c_int) -> io::Result<()> where F: FnMut(&[u8], u32) -> io::Result<()>
{ {
// pcinfo may return an arbitrary number of file:line pairs, // pcinfo may return an arbitrary number of file:line pairs,
// in the order of stack trace (i.e. inlined calls first). // in the order of stack trace (i.e. inlined calls first).
// in order to avoid allocation, we stack-allocate a fixed size of entries. // in order to avoid allocation, we stack-allocate a fixed size of entries.
const FILELINE_SIZE: usize = 32; const FILELINE_SIZE: usize = 32;
let mut fileline_buf = [(ptr::null(), -1); FILELINE_SIZE]; let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE];
let ret; let ret;
let fileline_count = { let fileline_count = {
let state = unsafe { init_state() }; let state = unsafe { init_state() };
@ -136,7 +136,7 @@ extern {
// helper callbacks // helper callbacks
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
type FileLine = (*const libc::c_char, libc::c_int); type FileLine = (*const libc::c_char, u32);
extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char, extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char,
_errnum: libc::c_int) { _errnum: libc::c_int) {
@ -162,7 +162,7 @@ extern fn pcinfo_cb(data: *mut libc::c_void,
// if the buffer is not full, add file:line to the buffer // if the buffer is not full, add file:line to the buffer
// and adjust the buffer for next possible calls to pcinfo_cb. // and adjust the buffer for next possible calls to pcinfo_cb.
if !buffer.is_empty() { if !buffer.is_empty() {
buffer[0] = (filename, lineno); buffer[0] = (filename, lineno as u32);
unsafe { ptr::write(slot, &mut buffer[1..]); } unsafe { ptr::write(slot, &mut buffer[1..]); }
} }
} }

View file

@ -10,12 +10,11 @@
use env; use env;
use alloc::boxed::FnBox; use alloc::boxed::FnBox;
use libc;
use sync::atomic::{self, Ordering}; use sync::atomic::{self, Ordering};
use sys::stack_overflow; use sys::stack_overflow;
use sys::thread as imp; use sys::thread as imp;
pub unsafe fn start_thread(main: *mut libc::c_void) { pub unsafe fn start_thread(main: *mut u8) {
// Next, set up our stack overflow handler which may get triggered if we run // Next, set up our stack overflow handler which may get triggered if we run
// out of stack. // out of stack.
let _handler = stack_overflow::Handler::new(); let _handler = stack_overflow::Handler::new();