diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs index 1a463a499cb41..342d0828f82f1 100644 --- a/src/libstd/logging.rs +++ b/src/libstd/logging.rs @@ -10,11 +10,11 @@ //! Logging +use fmt; use option::*; use os; use rt; use rt::logging::{Logger, StdErrLogger}; -use send_str::SendStrOwned; /// Turns on logging to stdout globally pub fn console_on() { @@ -37,7 +37,17 @@ pub fn console_off() { rt::logging::console_off(); } -fn newsched_log_str(msg: ~str) { +#[cfg(stage0)] +#[doc(hidden)] +pub fn log(_level: u32, s: ~str) { + // this is a terrible approximation, but it gets the job done (for stage0 at + // least) + ::io::println(s); +} + +#[allow(missing_doc)] +#[cfg(not(stage0))] +pub fn log(_level: u32, args: &fmt::Arguments) { use rt::task::Task; use rt::local::Local; @@ -46,20 +56,13 @@ fn newsched_log_str(msg: ~str) { match optional_task { Some(local) => { // Use the available logger - (*local).logger.log(SendStrOwned(msg)); + (*local).logger.log(args); } None => { // There is no logger anywhere, just write to stderr let mut logger = StdErrLogger; - logger.log(SendStrOwned(msg)); + logger.log(args); } } } } - -// XXX: This will change soon to not require an allocation. This is an unstable -// api which should not be used outside of the macros in ext/expand. -#[doc(hidden)] -pub fn log(_level: u32, msg: ~str) { - newsched_log_str(msg); -} diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs index 3dbf7a918b7a8..cfbc53ad34e00 100644 --- a/src/libstd/rt/logging.rs +++ b/src/libstd/rt/logging.rs @@ -7,9 +7,12 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. + +use fmt; use from_str::from_str; -use libc::{uintptr_t, exit, STDERR_FILENO}; +use libc::{uintptr_t, exit}; use option::{Some, None, Option}; +use rt; use rt::util::dumb_println; use rt::crate_map::{ModEntry, iter_crate_map}; use rt::crate_map::get_crate_map; @@ -18,7 +21,6 @@ use str::raw::from_c_str; use u32; use vec::ImmutableVector; use cast::transmute; -use send_str::{SendStr, SendStrOwned, SendStrStatic}; struct LogDirective { name: Option<~str>, @@ -171,44 +173,33 @@ fn update_log_settings(crate_map: *u8, settings: ~str) { } pub trait Logger { - fn log(&mut self, msg: SendStr); + fn log(&mut self, args: &fmt::Arguments); } pub struct StdErrLogger; impl Logger for StdErrLogger { - fn log(&mut self, msg: SendStr) { - use io::{Writer, WriterUtil}; - - if !should_log_console() { - return; + fn log(&mut self, args: &fmt::Arguments) { + if should_log_console() { + fmt::write(self as &mut rt::io::Writer, args); } + } +} - let s: &str = match msg { - SendStrOwned(ref s) => { - let slc: &str = *s; - slc - }, - SendStrStatic(s) => s, - }; - - // Truncate the string - let buf_bytes = 2048; - if s.len() > buf_bytes { - let s = s.slice(0, buf_bytes) + "[...]"; - print(s); - } else { - print(s) - }; - - fn print(s: &str) { - let dbg = STDERR_FILENO as ::io::fd_t; - dbg.write_str(s); - dbg.write_str("\n"); - dbg.flush(); - } +impl rt::io::Writer for StdErrLogger { + fn write(&mut self, buf: &[u8]) { + // Nothing like swapping between I/O implementations! In theory this + // could use the libuv bindings for writing to file descriptors, but + // that may not necessarily be desirable because logging should work + // outside of the uv loop. (modify with caution) + use io::Writer; + let dbg = ::libc::STDERR_FILENO as ::io::fd_t; + dbg.write(buf); } + + fn flush(&mut self) {} } + /// Configure logging by traversing the crate map and setting the /// per-module global logging flags based on the logging spec pub fn init() { diff --git a/src/libstd/std.rs b/src/libstd/std.rs index 5c1bac7418e6f..b06385cbcf422 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -224,4 +224,5 @@ mod std { pub use os; pub use fmt; pub use to_bytes; + pub use logging; } diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index c315c3f9dfc5e..c38f3525867cc 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -125,14 +125,41 @@ impl FailWithCause for &'static str { } } -// FIXME #4427: Temporary until rt::rt_fail_ goes away +// This stage0 version is incredibly wrong. +#[cfg(stage0)] pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { use option::{Some, None}; use rt::in_green_task_context; use rt::task::Task; use rt::local::Local; use rt::logging::Logger; - use send_str::SendStrOwned; + use str::Str; + + unsafe { + let msg = str::raw::from_c_str(msg); + let file = str::raw::from_c_str(file); + if in_green_task_context() { + rterrln!("task failed at '%s', %s:%i", msg, file, line as int); + } else { + rterrln!("failed in non-task context at '%s', %s:%i", + msg, file, line as int); + } + + let task: *mut Task = Local::unsafe_borrow(); + if (*task).unwinder.unwinding { + rtabort!("unwinding again"); + } + (*task).unwinder.begin_unwind(); + } +} + +// FIXME #4427: Temporary until rt::rt_fail_ goes away +#[cfg(not(stage0))] +pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { + use rt::in_green_task_context; + use rt::task::Task; + use rt::local::Local; + use rt::logging::Logger; use str::Str; unsafe { @@ -140,22 +167,14 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { let msg = str::raw::from_c_str(msg); let file = str::raw::from_c_str(file); - // XXX: Logging doesn't work correctly in non-task context because it - // invokes the local heap if in_green_task_context() { - // XXX: Logging doesn't work here - the check to call the log - // function never passes - so calling the log function directly. + // Be careful not to allocate in this block, if we're failing we may + // have been failing due to a lack of memory in the first place... do Local::borrow |task: &mut Task| { - let msg = match task.name { - Some(ref name) => - fmt!("task '%s' failed at '%s', %s:%i", - name.as_slice(), msg, file, line as int), - None => - fmt!("task failed at '%s', %s:%i", - msg, file, line as int) - }; - - task.logger.log(SendStrOwned(msg)); + let n = task.name.map(|n| n.as_slice()).unwrap_or(""); + format_args!(|args| { task.logger.log(args) }, + "task '{}' failed at '{}', {}:{}", + n, msg.as_slice(), file.as_slice(), line); } } else { rterrln!("failed in non-task context at '%s', %s:%i", diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 64f30803ca734..80cb9424fa10a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -813,13 +813,17 @@ pub fn std_macros() -> @str { ($lvl:expr, $arg:expr) => ({ let lvl = $lvl; if lvl <= __log_level() { - ::std::logging::log(lvl, fmt!(\"%?\", $arg)) + format_args!(|args| { + ::std::logging::log(lvl, args) + }, \"{}\", fmt!(\"%?\", $arg)) } }); ($lvl:expr, $($arg:expr),+) => ({ let lvl = $lvl; if lvl <= __log_level() { - ::std::logging::log(lvl, fmt!($($arg),+)) + format_args!(|args| { + ::std::logging::log(lvl, args) + }, \"{}\", fmt!($($arg),+)) } }) ) @@ -834,7 +838,9 @@ pub fn std_macros() -> @str { ($lvl:expr, $($arg:tt)+) => ({ let lvl = $lvl; if lvl <= __log_level() { - ::std::logging::log(lvl, format!($($arg)+)) + format_args!(|args| { + ::std::logging::log(lvl, args) + }, $($arg)+) } }) ) diff --git a/src/test/compile-fail/issue-2823.rs b/src/test/compile-fail/issue-2823.rs index bf00dc139d0f5..58b216e8d119b 100644 --- a/src/test/compile-fail/issue-2823.rs +++ b/src/test/compile-fail/issue-2823.rs @@ -20,6 +20,5 @@ impl Drop for C { fn main() { let c = C{ x: 2}; - let d = c.clone(); //~ ERROR does not implement any method in scope - error!("%?", d.x); + let _d = c.clone(); //~ ERROR does not implement any method in scope } diff --git a/src/test/run-fail/rt-log-trunc.rs b/src/test/run-fail/rt-log-trunc.rs deleted file mode 100644 index 1dd27d7d3ae20..0000000000000 --- a/src/test/run-fail/rt-log-trunc.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that logs add `[...]` to truncated lines -// error-pattern:[...] - -fn main() { - fail!("\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ - "); -}