about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-15 23:01:24 -0700
committerbors <bors@rust-lang.org>2014-03-15 23:01:24 -0700
commitf6fcdbb68718380beca798d087c46152cad0949c (patch)
treec6b7fd10bb869fba19561852cf4eb286b0f96a4f /src/libstd
parentabd844e4df068196d1150ac39d596f73e210d95d (diff)
parent0015cab1fd7b4b47030c808a825bb5594cc1d4ac (diff)
downloadrust-f6fcdbb68718380beca798d087c46152cad0949c.tar.gz
rust-f6fcdbb68718380beca798d087c46152cad0949c.zip
auto merge of #12791 : alexcrichton/rust/liblog, r=brson
The rationale and modifications can be found in the first commit message.

This does make logging a bit more painful to use initially because it involves a feature gate and some `phase` attributes, but I think it may be reasonable to not require the `phase` attribute for loading `macro_rules!` macros because defining them will still be gated.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/cleanup.rs2
-rw-r--r--src/libstd/io/mod.rs4
-rw-r--r--src/libstd/io/test.rs9
-rw-r--r--src/libstd/iter.rs4
-rw-r--r--src/libstd/lib.rs5
-rw-r--r--src/libstd/logging.rs184
-rw-r--r--src/libstd/macros.rs113
-rw-r--r--src/libstd/os.rs21
-rw-r--r--src/libstd/ptr.rs3
-rw-r--r--src/libstd/rt/backtrace.rs22
-rw-r--r--src/libstd/rt/crate_map.rs99
-rw-r--r--src/libstd/rt/logging.rs314
-rw-r--r--src/libstd/rt/mod.rs4
-rw-r--r--src/libstd/rt/task.rs5
-rw-r--r--src/libstd/rt/unwind.rs2
-rw-r--r--src/libstd/task.rs4
16 files changed, 63 insertions, 732 deletions
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
index 39c7932cdc8..243f7b2055f 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -97,6 +97,6 @@ pub unsafe fn annihilate() {
 
     if debug_mem() {
         // We do logging here w/o allocation.
-        debug!("total boxes annihilated: {}", n_total_boxes);
+        println!("total boxes annihilated: {}", n_total_boxes);
     }
 }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 28f6d13070e..c18d4e273c4 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -352,9 +352,7 @@ pub trait Reader {
         let mut buf = [0];
         loop {
             match self.read(buf) {
-                Ok(0) => {
-                    debug!("read 0 bytes. trying again");
-                }
+                Ok(0) => {}
                 Ok(1) => return Ok(buf[0]),
                 Ok(_) => unreachable!(),
                 Err(e) => return Err(e)
diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs
index a3e5bac89d6..9eeaf4635a4 100644
--- a/src/libstd/io/test.rs
+++ b/src/libstd/io/test.rs
@@ -176,16 +176,14 @@ mod darwin_fd_limit {
         if sysctl(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size,
                   mut_null(), 0) != 0 {
             let err = last_os_error();
-            error!("raise_fd_limit: error calling sysctl: {}", err);
-            return;
+            fail!("raise_fd_limit: error calling sysctl: {}", err);
         }
 
         // Fetch the current resource limits
         let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
         if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
             let err = last_os_error();
-            error!("raise_fd_limit: error calling getrlimit: {}", err);
-            return;
+            fail!("raise_fd_limit: error calling getrlimit: {}", err);
         }
 
         // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit
@@ -194,8 +192,7 @@ mod darwin_fd_limit {
         // Set our newly-increased resource limit
         if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
             let err = last_os_error();
-            error!("raise_fd_limit: error calling setrlimit: {}", err);
-            return;
+            fail!("raise_fd_limit: error calling setrlimit: {}", err);
         }
     }
 }
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 6bcac425420..9e988eb4094 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -398,9 +398,9 @@ pub trait Iterator<A> {
     /// let xs = [1u, 4, 2, 3, 8, 9, 6];
     /// let sum = xs.iter()
     ///             .map(|&x| x)
-    ///             .inspect(|&x| debug!("filtering {}", x))
+    ///             .inspect(|&x| println!("filtering {}", x))
     ///             .filter(|&x| x % 2 == 0)
-    ///             .inspect(|&x| debug!("{} made it through", x))
+    ///             .inspect(|&x| println!("{} made it through", x))
     ///             .sum();
     /// println!("{}", sum);
     /// ```
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 6b1773ec7ff..17c0e2235c0 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -53,7 +53,7 @@
       html_root_url = "http://static.rust-lang.org/doc/master")];
 
 #[feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args,
-          simd, linkage, default_type_params)];
+          simd, linkage, default_type_params, phase)];
 
 // NOTE remove the following two attributes after the next snapshot.
 #[allow(unrecognized_lint)];
@@ -73,6 +73,7 @@
 #[cfg(test)] extern crate rustuv;
 #[cfg(test)] extern crate native;
 #[cfg(test)] extern crate green;
+#[cfg(test)] #[phase(syntax, link)] extern crate log;
 
 // Make and rand accessible for benchmarking/testcases
 #[cfg(test)] extern crate rand;
@@ -178,7 +179,6 @@ pub mod path;
 pub mod cast;
 pub mod fmt;
 pub mod cleanup;
-pub mod logging;
 pub mod mem;
 
 
@@ -221,7 +221,6 @@ mod std {
     pub use io;
     pub use kinds;
     pub use local_data;
-    pub use logging;
     pub use option;
     pub use os;
     pub use rt;
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
deleted file mode 100644
index 2271a7c2380..00000000000
--- a/src/libstd/logging.rs
+++ /dev/null
@@ -1,184 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Utilities for program-wide and customizable logging
-
-This module is used by the compiler when emitting output for the logging family
-of macros. The methods of this module shouldn't necessarily be used directly,
-but rather through the logging macros defined.
-
-There are five macros that the logging subsystem uses:
-
-* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
-                       related `format!` arguments
-* `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
-* `info!(...)` - a macro hard-wired to the log level of `INFO`
-* `warn!(...)` - a macro hard-wired to the log level of `WARN`
-* `error!(...)` - a macro hard-wired to the log level of `ERROR`
-
-All of these macros use the same style of syntax as the `format!` syntax
-extension. Details about the syntax can be found in the documentation of
-`std::fmt` along with the Rust tutorial/manual.
-
-If you want to check at runtime if a given logging level is enabled (e.g. if the
-information you would want to log is expensive to produce), you can use the
-following macro:
-
-* `log_enabled!(level)` - returns true if logging of the given level is enabled
-
-## Enabling logging
-
-Log levels are controlled on a per-module basis, and by default all logging is
-disabled except for `error!` (a log level of 1). Logging is controlled via the
-`RUST_LOG` environment variable. The value of this environment variable is a
-comma-separated list of logging directives. A logging directive is of the form:
-
-```ignore
-path::to::module=log_level
-```
-
-The path to the module is rooted in the name of the crate it was compiled for,
-so if your program is contained in a file `hello.rs`, for example, to turn on
-logging for this file you would use a value of `RUST_LOG=hello`. Furthermore,
-this path is a prefix-search, so all modules nested in the specified module will
-also have logging enabled.
-
-The actual `log_level` is optional to specify. If omitted, all logging will be
-enabled. If specified, the it must be either a numeric in the range of 1-255, or
-it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
-is specified, then all logging less than or equal to that numeral is enabled.
-For example, if logging level 3 is active, error, warn, and info logs will be
-printed, but debug will be omitted.
-
-As the log level for a module is optional, the module to enable logging for is
-also optional. If only a `log_level` is provided, then the global log level for
-all modules is set to this value.
-
-Some examples of valid values of `RUST_LOG` are:
-
-```ignore
-hello                // turns on all logging for the 'hello' module
-info                 // turns on all info logging
-hello=debug          // turns on debug logging for 'hello'
-hello=3              // turns on info logging for 'hello'
-hello,std::option    // turns on hello, and std's option logging
-error,hello=warn     // turn on global error logging and also warn for hello
-```
-
-## Performance and Side Effects
-
-Each of these macros will expand to code similar to:
-
-```rust,ignore
-if log_level <= my_module_log_level() {
-    ::std::logging::log(log_level, format!(...));
-}
-```
-
-What this means is that each of these macros are very cheap at runtime if
-they're turned off (just a load and an integer comparison). This also means that
-if logging is disabled, none of the components of the log will be executed.
-
-## Useful Values
-
-For convenience, if a value of `::help` is set for `RUST_LOG`, a program will
-start, print out all modules registered for logging, and then exit.
-
-*/
-
-use fmt;
-use io::LineBufferedWriter;
-use io;
-use io::Writer;
-use mem::replace;
-use ops::Drop;
-use option::{Some, None, Option};
-use prelude::drop;
-use result::{Ok, Err};
-use rt::local::Local;
-use rt::task::Task;
-
-/// Debug log level
-pub static DEBUG: u32 = 4;
-/// Info log level
-pub static INFO: u32 = 3;
-/// Warn log level
-pub static WARN: u32 = 2;
-/// Error log level
-pub static ERROR: u32 = 1;
-
-/// A trait used to represent an interface to a task-local logger. Each task
-/// can have its own custom logger which can respond to logging messages
-/// however it likes.
-pub trait Logger {
-    /// Logs a single message described by the `args` structure. The level is
-    /// provided in case you want to do things like color the message, etc.
-    fn log(&mut self, level: u32, args: &fmt::Arguments);
-}
-
-struct DefaultLogger {
-    handle: LineBufferedWriter<io::stdio::StdWriter>,
-}
-
-impl Logger for DefaultLogger {
-    // by default, just ignore the level
-    fn log(&mut self, _level: u32, args: &fmt::Arguments) {
-        match fmt::writeln(&mut self.handle, args) {
-            Err(e) => fail!("failed to log: {}", e),
-            Ok(()) => {}
-        }
-    }
-}
-
-impl Drop for DefaultLogger {
-    fn drop(&mut self) {
-        match self.handle.flush() {
-            Err(e) => fail!("failed to flush a logger: {}", e),
-            Ok(()) => {}
-        }
-    }
-}
-
-/// This function is called directly by the compiler when using the logging
-/// macros. This function does not take into account whether the log level
-/// specified is active or not, it will always log something if this method is
-/// called.
-///
-/// It is not recommended to call this function directly, rather it should be
-/// invoked through the logging family of macros.
-pub fn log(level: u32, args: &fmt::Arguments) {
-    // See io::stdio::with_task_stdout for why there's a few dances here. The
-    // gist of it is that arbitrary code can run during logging (and set an
-    // arbitrary logging handle into the task) so we need to be careful that the
-    // local task is in TLS while we're running arbitrary code.
-    let mut logger = {
-        let mut task = Local::borrow(None::<Task>);
-        task.get().logger.take()
-    };
-
-    if logger.is_none() {
-        logger = Some(~DefaultLogger { handle: io::stderr(), } as ~Logger);
-    }
-    logger.get_mut_ref().log(level, args);
-
-    let mut task = Local::borrow(None::<Task>);
-    let prev = replace(&mut task.get().logger, logger);
-    drop(task);
-    drop(prev);
-}
-
-/// Replaces the task-local logger with the specified logger, returning the old
-/// logger.
-pub fn set_logger(logger: ~Logger) -> Option<~Logger> {
-    let mut task = Local::borrow(None::<Task>);
-    replace(&mut task.get().logger, Some(logger))
-}
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index ece9c1bfd20..6d96ea94d31 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -16,107 +16,6 @@
 
 #[macro_escape];
 
-/// The standard logging macro
-///
-/// This macro will generically log over a provided level (of type u32) with a
-/// format!-based argument list. See documentation in `std::fmt` for details on
-/// how to use the syntax, and documentation in `std::logging` for info about
-/// logging macros.
-///
-/// # Example
-///
-/// ```
-/// log!(::std::logging::DEBUG, "this is a debug message");
-/// log!(::std::logging::WARN, "this is a warning {}", "message");
-/// log!(6, "this is a custom logging level: {level}", level=6);
-/// ```
-#[macro_export]
-macro_rules! log(
-    ($lvl:expr, $($arg:tt)+) => ({
-        let lvl = $lvl;
-        if lvl <= __log_level() {
-            format_args!(|args| {
-                ::std::logging::log(lvl, args)
-            }, $($arg)+)
-        }
-    })
-)
-
-/// A convenience macro for logging at the error log level. See `std::logging`
-/// for more information. about logging.
-///
-/// # Example
-///
-/// ```
-/// # let error = 3;
-/// error!("the build has failed with error code: {}", error);
-/// ```
-#[macro_export]
-macro_rules! error(
-    ($($arg:tt)*) => (log!(1u32, $($arg)*))
-)
-
-/// A convenience macro for logging at the warning log level. See `std::logging`
-/// for more information. about logging.
-///
-/// # Example
-///
-/// ```
-/// # let code = 3;
-/// warn!("you may like to know that a process exited with: {}", code);
-/// ```
-#[macro_export]
-macro_rules! warn(
-    ($($arg:tt)*) => (log!(2u32, $($arg)*))
-)
-
-/// A convenience macro for logging at the info log level. See `std::logging`
-/// for more information. about logging.
-///
-/// # Example
-///
-/// ```
-/// # let ret = 3;
-/// info!("this function is about to return: {}", ret);
-/// ```
-#[macro_export]
-macro_rules! info(
-    ($($arg:tt)*) => (log!(3u32, $($arg)*))
-)
-
-/// A convenience macro for logging at the debug log level. See `std::logging`
-/// for more information. about logging.
-///
-/// # Example
-///
-/// ```
-/// debug!("x = {x}, y = {y}", x=10, y=20);
-/// ```
-#[macro_export]
-macro_rules! debug(
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(4u32, $($arg)*) })
-)
-
-/// A macro to test whether a log level is enabled for the current module.
-///
-/// # Example
-///
-/// ```
-/// # struct Point { x: int, y: int }
-/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
-/// if log_enabled!(std::logging::DEBUG) {
-///     let x = some_expensive_computation();
-///     debug!("x.x = {}, x.y = {}", x.x, x.y);
-/// }
-/// ```
-#[macro_export]
-macro_rules! log_enabled(
-    ($lvl:expr) => ({
-        let lvl = $lvl;
-        lvl <= __log_level() && (lvl != 4 || cfg!(not(ndebug)))
-    })
-)
-
 /// The entry point for failure of rust tasks.
 ///
 /// This macro is used to inject failure into a rust task, causing the task to
@@ -421,3 +320,15 @@ macro_rules! select {
         { unreachable!() }
     })
 }
+
+// When testing the standard library, we link to the liblog crate to get the
+// logging macros. In doing so, the liblog crate was linked against the real
+// version of libstd, and uses a different std::fmt module than the test crate
+// uses. To get around this difference, we redefine the log!() macro here to be
+// just a dumb version of what it should be.
+#[cfg(test)]
+macro_rules! log (
+    ($lvl:expr, $($args:tt)*) => (
+        if log_enabled!($lvl) { println!($($args)*) }
+    )
+)
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index b8f00d1b692..040d5c0e175 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -1127,14 +1127,8 @@ impl Drop for MemoryMap {
         if self.len == 0 { /* workaround for dummy_stack */ return; }
 
         unsafe {
-            match libc::munmap(self.data as *c_void, self.len as libc::size_t) {
-                0 => (),
-                -1 => match errno() as c_int {
-                    libc::EINVAL => error!("invalid addr or len"),
-                    e => error!("unknown errno={}", e)
-                },
-                r => error!("Unexpected result {}", r)
-            }
+            // FIXME: what to do if this fails?
+            let _ = libc::munmap(self.data as *c_void, self.len as libc::size_t);
         }
     }
 }
@@ -1161,10 +1155,7 @@ impl MemoryMap {
                 MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
                 MapFd(fd_) => { fd = fd_; },
                 MapOffset(offset_) => { offset = offset_; },
-                MapNonStandardFlags(f) => {
-                    info!("MemoryMap::new: MapNonStandardFlags used on \
-                           Windows: {}", f)
-                }
+                MapNonStandardFlags(..) => {}
             }
         }
 
@@ -1262,15 +1253,15 @@ impl Drop for MemoryMap {
                 MapVirtual => {
                     if libc::VirtualFree(self.data as *mut c_void, 0,
                                          libc::MEM_RELEASE) == 0 {
-                        error!("VirtualFree failed: {}", errno());
+                        println!("VirtualFree failed: {}", errno());
                     }
                 },
                 MapFile(mapping) => {
                     if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE {
-                        error!("UnmapViewOfFile failed: {}", errno());
+                        println!("UnmapViewOfFile failed: {}", errno());
                     }
                     if libc::CloseHandle(mapping as HANDLE) == FALSE {
-                        error!("CloseHandle failed: {}", errno());
+                        println!("CloseHandle failed: {}", errno());
                     }
                 }
             }
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 95eda1cecc0..bf5ba6db5c3 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -163,7 +163,6 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
   SAFETY NOTE: Pointer-arithmetic. Dragons be here.
 */
 pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
-    debug!("array_each_with_len: before iterate");
     if arr.is_null() {
         fail!("ptr::array_each_with_len failure: arr input is null pointer");
     }
@@ -172,7 +171,6 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
         let n = arr.offset(e as int);
         cb(*n);
     }
-    debug!("array_each_with_len: after iterate");
 }
 
 /**
@@ -189,7 +187,6 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
         fail!("ptr::array_each_with_len failure: arr input is null pointer");
     }
     let len = buf_len(arr);
-    debug!("array_each inferred len: {}", len);
     array_each_with_len(arr, len, cb);
 }
 
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 831f6c73e35..bc75a98e085 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -16,15 +16,31 @@ use from_str::from_str;
 use io::{IoResult, Writer};
 use iter::Iterator;
 use option::{Some, None};
+use os;
 use result::{Ok, Err};
 use str::StrSlice;
+use sync::atomics;
 
 pub use self::imp::write;
 
-// This function is defined in this module so that the way to enable logging of
-// backtraces has the word 'backtrace' in it: std::rt::backtrace.
+// For now logging is turned off by default, and this function checks to see
+// whether the magical environment variable is present to see if it's turned on.
 pub fn log_enabled() -> bool {
-    log_enabled!(::logging::DEBUG)
+    static mut ENABLED: atomics::AtomicInt = atomics::INIT_ATOMIC_INT;
+    unsafe {
+        match ENABLED.load(atomics::SeqCst) {
+            1 => return false,
+            2 => return true,
+            _ => {}
+        }
+    }
+
+    let val = match os::getenv("RUST_BACKTRACE") {
+        Some(..) => 2,
+        None => 1,
+    };
+    unsafe { ENABLED.store(val, atomics::SeqCst); }
+    val == 2
 }
 
 #[cfg(target_word_size = "64")] static HEX_WIDTH: uint = 18;
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index ff54a80ce99..c6d5a80208b 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -9,13 +9,14 @@
 // except according to those terms.
 
 use cast;
-use cmp::TotalOrd;
-use container::MutableSet;
-use iter::Iterator;
 use option::{Some, None, Option};
 use ptr::RawPtr;
 use rt::rtio::EventLoop;
-use vec::{ImmutableVector, OwnedVector};
+
+#[cfg(stage0)] use cmp::TotalOrd;
+#[cfg(stage0)] use container::MutableSet;
+#[cfg(stage0)] use iter::Iterator;
+#[cfg(stage0)] use vec::{ImmutableVector, OwnedVector};
 
 // Need to tell the linker on OS X to not barf on undefined symbols
 // and instead look them up at runtime, which we need to resolve
@@ -24,17 +25,24 @@ use vec::{ImmutableVector, OwnedVector};
 #[link_args = "-Wl,-U,__rust_crate_map_toplevel"]
 extern {}
 
+#[cfg(stage0)]
 pub struct ModEntry<'a> {
     name: &'a str,
     log_level: *mut u32
 }
 
+#[cfg(stage0)]
 pub struct CrateMap<'a> {
     version: i32,
     entries: &'a [ModEntry<'a>],
     children: &'a [&'a CrateMap<'a>],
     event_loop_factory: Option<fn() -> ~EventLoop>,
 }
+#[cfg(not(stage0))]
+pub struct CrateMap<'a> {
+    version: i32,
+    event_loop_factory: Option<fn() -> ~EventLoop>,
+}
 
 // When working on android, apparently weak symbols don't work so well for
 // finding the crate map, and neither does dlopen + dlsym. This is mainly a
@@ -114,6 +122,7 @@ pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
     }
 }
 
+#[cfg(stage0)]
 fn version(crate_map: &CrateMap) -> i32 {
     match crate_map.version {
         2 => return 2,
@@ -121,6 +130,7 @@ fn version(crate_map: &CrateMap) -> i32 {
     }
 }
 
+#[cfg(stage0)]
 fn do_iter_crate_map<'a>(
                      crate_map: &'a CrateMap<'a>,
                      f: |&'a ModEntry<'a>|,
@@ -149,87 +159,8 @@ fn do_iter_crate_map<'a>(
 }
 
 /// Iterates recursively over `crate_map` and all child crate maps
+#[cfg(stage0)]
 pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&'a ModEntry<'a>|) {
     let mut v = ~[];
     do_iter_crate_map(crate_map, f, &mut v);
 }
-
-#[cfg(test)]
-mod tests {
-    use option::None;
-    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
-
-    #[test]
-    fn iter_crate_map_duplicates() {
-        let mut level3: u32 = 3;
-
-        let entries = [
-            ModEntry { name: "c::m1", log_level: &mut level3},
-        ];
-
-        let child_crate = CrateMap {
-            version: 2,
-            entries: entries,
-            children: &[],
-            event_loop_factory: None,
-        };
-
-        let root_crate = CrateMap {
-            version: 2,
-            entries: &[],
-            children: &[&child_crate, &child_crate],
-            event_loop_factory: None,
-        };
-
-        let mut cnt = 0;
-        unsafe {
-            iter_crate_map(&root_crate, |entry| {
-                assert!(*entry.log_level == 3);
-                cnt += 1;
-            });
-            assert!(cnt == 1);
-        }
-    }
-
-    #[test]
-    fn iter_crate_map_follow_children() {
-        let mut level2: u32 = 2;
-        let mut level3: u32 = 3;
-        let child_crate2 = CrateMap {
-            version: 2,
-            entries: &[
-                ModEntry { name: "c::m1", log_level: &mut level2},
-                ModEntry { name: "c::m2", log_level: &mut level3},
-            ],
-            children: &[],
-            event_loop_factory: None,
-        };
-
-        let child_crate1 = CrateMap {
-            version: 2,
-            entries: &[
-                ModEntry { name: "t::f1", log_level: &mut 1},
-            ],
-            children: &[&child_crate2],
-            event_loop_factory: None,
-        };
-
-        let root_crate = CrateMap {
-            version: 2,
-            entries: &[
-                ModEntry { name: "t::f2", log_level: &mut 0},
-            ],
-            children: &[&child_crate1],
-            event_loop_factory: None,
-        };
-
-        let mut cnt = 0;
-        unsafe {
-            iter_crate_map(&root_crate, |entry| {
-                assert!(*entry.log_level == cnt);
-                cnt += 1;
-            });
-            assert!(cnt == 4);
-        }
-    }
-}
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
deleted file mode 100644
index aa024a53b89..00000000000
--- a/src/libstd/rt/logging.rs
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2013 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::Container;
-use from_str::from_str;
-use iter::Iterator;
-use libc::exit;
-use option::{Some, None, Option};
-use os;
-use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
-use str::{Str, StrSlice};
-use vec::{ImmutableVector, MutableTotalOrdVector, OwnedVector};
-use vec_ng::Vec;
-
-struct LogDirective<'a> {
-    name: Option<&'a str>,
-    level: u32
-}
-
-static MAX_LOG_LEVEL: u32 = 255;
-static DEFAULT_LOG_LEVEL: u32 = 1;
-static log_level_names : &'static[&'static str] = &'static["error", "warn", "info", "debug"];
-
-/// Parse an individual log level that is either a number or a symbolic log level
-fn parse_log_level(level: &str) -> Option<u32> {
-    let num = from_str::<u32>(level);
-    let mut log_level;
-    match num {
-        Some(num) => {
-            if num < MAX_LOG_LEVEL {
-                log_level = Some(num);
-            } else {
-                log_level = Some(MAX_LOG_LEVEL);
-            }
-        }
-        _ => {
-            let position = log_level_names.iter().position(|&name| name == level);
-            match position {
-                Some(position) => {
-                    log_level = Some(::cmp::min(MAX_LOG_LEVEL, (position + 1) as u32))
-                },
-                _ => {
-                    log_level = None;
-                }
-            }
-        }
-    }
-    log_level
-}
-
-/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1")
-/// and return a vector with log directives.
-/// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in std::).
-/// Also supports string log levels of error, warn, info, and debug
-fn parse_logging_spec<'a>(spec: &'a str) -> Vec<LogDirective<'a>> {
-    let mut dirs = Vec::new();
-    for s in spec.split(',') {
-        if s.len() == 0 { continue }
-        let mut parts = s.split('=');
-        let log_level;
-        let name;
-        match (parts.next(), parts.next(), parts.next()) {
-            (Some(part0), None, None) => {
-                //if the single argument is a log-level string or number,
-                //treat that as a global fallback
-                let possible_log_level = parse_log_level(part0);
-                match possible_log_level {
-                    Some(num) => {
-                        name = None;
-                        log_level = num;
-                    },
-                    None => {
-                        log_level = MAX_LOG_LEVEL;
-                        name = Some(part0);
-                    }
-                }
-            }
-            (Some(part0), Some(part1), None) => {
-                let possible_log_level = parse_log_level(part1);
-                match possible_log_level {
-                    Some(num) => {
-                        name = Some(part0);
-                        log_level = num;
-                    },
-                    _ => {
-                        rterrln!("warning: invalid logging spec '{}', \
-                                  ignoring it", part1);
-                        continue
-                    }
-                }
-            },
-            _ => {
-                rterrln!("warning: invalid logging spec '{}', \
-                          ignoring it", s);
-                continue
-            }
-        }
-        dirs.push(LogDirective { name: name, level: log_level });
-    }
-    return dirs;
-}
-
-/// Set the log level of an entry in the crate map depending on the vector
-/// of log directives
-fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
-    let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
-    let mut longest_match = -1i;
-    for dir in dirs.iter() {
-        match dir.name {
-            None => {
-                if longest_match == -1 {
-                    longest_match = 0;
-                    new_lvl = dir.level;
-                }
-            }
-            Some(ref dir_name) => {
-                let name = entry.name;
-                let len = dir_name.len() as int;
-                if name.starts_with(*dir_name) &&
-                    len >= longest_match {
-                    longest_match = len;
-                    new_lvl = dir.level;
-                }
-            }
-        };
-    }
-    unsafe { *entry.log_level = new_lvl; }
-    if longest_match >= 0 { return 1; } else { return 0; }
-}
-
-/// Set log level for every entry in crate_map according to the sepecification
-/// in settings
-fn update_log_settings(crate_map: &CrateMap, settings: &str) {
-    if settings == "::help" || settings == "?" {
-        rterrln!("\nCrate log map:\n");
-
-        let mut entries = Vec::new();
-        iter_crate_map(crate_map, |entry| entries.push(entry.name));
-        entries.as_mut_slice().sort();
-
-        for name in entries.iter() {
-            rterrln!(" {}", *name);
-        }
-        unsafe { exit(1); }
-    }
-    let dirs = parse_logging_spec(settings);
-
-    let mut n_matches: u32 = 0;
-    iter_crate_map(crate_map, |entry| {
-        let m = update_entry(dirs.as_slice(), entry);
-        n_matches += m;
-    });
-
-    if n_matches < (dirs.len() as u32) {
-        rterrln!("warning: got {} RUST_LOG specs but only matched\n\
-                  {} of them. You may have mistyped a RUST_LOG spec. \n\
-                  Use RUST_LOG=::help to see the list of crates and modules.\n",
-                 dirs.len(), n_matches);
-    }
-}
-
-/// Configure logging by traversing the crate map and setting the
-/// per-module global logging flags based on the logging spec
-pub fn init() {
-    let log_spec = os::getenv("RUST_LOG");
-    match get_crate_map() {
-        Some(crate_map) => {
-            match log_spec {
-                Some(spec) => update_log_settings(crate_map, spec.as_slice()),
-                None => update_log_settings(crate_map, ""),
-            }
-        },
-        _ => {
-            match log_spec {
-                Some(_) => {
-                    rterrln!("warning: RUST_LOG set, but no crate map found.");
-                },
-                None => {}
-            }
-        }
-    }
-}
-
-// Tests for parse_logging_spec()
-#[test]
-fn parse_logging_spec_valid() {
-    let dirs = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 3);
-    assert_eq!(dirs[0].name, Some("crate1::mod1"));
-    assert_eq!(dirs[0].level, 1);
-
-    assert_eq!(dirs[1].name, Some("crate1::mod2"));
-    assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
-
-    assert_eq!(dirs[2].name, Some("crate2"));
-    assert_eq!(dirs[2].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_invalid_crate() {
-    // test parse_logging_spec with multiple = in specification
-    let dirs = parse_logging_spec("crate1::mod1=1=2,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 1);
-    assert_eq!(dirs[0].name, Some("crate2"));
-    assert_eq!(dirs[0].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_invalid_log_level() {
-    // test parse_logging_spec with 'noNumber' as log level
-    let dirs = parse_logging_spec("crate1::mod1=noNumber,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 1);
-    assert_eq!(dirs[0].name, Some("crate2"));
-    assert_eq!(dirs[0].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_string_log_level() {
-    // test parse_logging_spec with 'warn' as log level
-    let dirs = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 1);
-    assert_eq!(dirs[0].name, Some("crate2"));
-    assert_eq!(dirs[0].level, 2);
-}
-
-#[test]
-fn parse_logging_spec_global() {
-    // test parse_logging_spec with no crate
-    let dirs = parse_logging_spec("warn,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 2);
-    assert_eq!(dirs[0].name, None);
-    assert_eq!(dirs[0].level, 2);
-    assert_eq!(dirs[1].name, Some("crate2"));
-    assert_eq!(dirs[1].level, 4);
-}
-
-// Tests for update_entry
-#[test]
-fn update_entry_match_full_path() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate1::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 2);
-}
-
-#[test]
-fn update_entry_no_match() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate3::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 0);
-    }
-    assert_eq!(level, DEFAULT_LOG_LEVEL);
-}
-
-#[test]
-fn update_entry_match_beginning() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 }];
-    let mut level = 0;
-    {
-        let entry= &ModEntry {name: "crate2::mod1", log_level: &mut level};
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 3);
-}
-
-#[test]
-fn update_entry_match_beginning_longest_match() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 },
-                LogDirective { name: Some("crate2::mod"), level: 4 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate2::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 4);
-}
-
-#[test]
-fn update_entry_match_default() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: None, level: 3 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate1::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 2);
-    {
-        let entry = &ModEntry { name: "crate2::mod2", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 3);
-}
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index a58826daa49..84e547619df 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -104,9 +104,6 @@ pub mod env;
 /// The local, managed heap
 pub mod local_heap;
 
-/// The Logger trait and implementations
-pub mod logging;
-
 /// Crate map
 pub mod crate_map;
 
@@ -183,7 +180,6 @@ pub fn init(argc: int, argv: **u8) {
     unsafe {
         args::init(argc, argv);
         env::init();
-        logging::init();
         local_ptr::init();
         at_exit_imp::init();
     }
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 86e69560e9d..8c617c1b59b 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -21,7 +21,6 @@ use comm::Sender;
 use io::Writer;
 use iter::{Iterator, Take};
 use local_data;
-use logging::Logger;
 use ops::Drop;
 use option::{Option, Some, None};
 use prelude::drop;
@@ -51,7 +50,6 @@ pub struct Task {
     destroyed: bool,
     name: Option<SendStr>,
 
-    logger: Option<~Logger>,
     stdout: Option<~Writer>,
     stderr: Option<~Writer>,
 
@@ -95,7 +93,6 @@ impl Task {
             death: Death::new(),
             destroyed: false,
             name: None,
-            logger: None,
             stdout: None,
             stderr: None,
             imp: None,
@@ -129,11 +126,9 @@ impl Task {
                 #[allow(unused_must_use)]
                 fn close_outputs() {
                     let mut task = Local::borrow(None::<Task>);
-                    let logger = task.get().logger.take();
                     let stderr = task.get().stderr.take();
                     let stdout = task.get().stdout.take();
                     drop(task);
-                    drop(logger); // loggers are responsible for flushing
                     match stdout { Some(mut w) => { w.flush(); }, None => {} }
                     match stderr { Some(mut w) => { w.flush(); }, None => {} }
                 }
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 3a06075ce48..7f54b8b3320 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -398,6 +398,8 @@ fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
                 if backtrace::log_enabled() {
                     let mut err = ::rt::util::Stderr;
                     let _err = backtrace::write(&mut err);
+                } else {
+                    rterrln!("run with `RUST_BACKTRACE=1` to see a backtrace");
                 }
                 unsafe { intrinsics::abort() }
             }
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index 19f41c6fa1c..9c88db6beb5 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -40,7 +40,6 @@ use any::Any;
 use comm::{Sender, Receiver, channel};
 use io::Writer;
 use kinds::{Send, marker};
-use logging::Logger;
 use option::{None, Some, Option};
 use result::{Result, Ok, Err};
 use rt::local::Local;
@@ -66,8 +65,6 @@ pub struct TaskOpts {
     name: Option<SendStr>,
     /// The size of the stack for the spawned task
     stack_size: Option<uint>,
-    /// Task-local logger (see std::logging)
-    logger: Option<~Logger>,
     /// Task-local stdout
     stdout: Option<~Writer>,
     /// Task-local stderr
@@ -230,7 +227,6 @@ impl TaskOpts {
             notify_chan: None,
             name: None,
             stack_size: None,
-            logger: None,
             stdout: None,
             stderr: None,
         }