diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index d31ca763209..7d772a997c1 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -119,6 +119,7 @@ use back::link; use lib::llvm::{ValueRef, llvm, SetLinkage, False}; use lib; use metadata::csearch; +use metadata::cstore; use middle::trans::_match; use middle::trans::adt; use middle::trans::asm; @@ -1799,9 +1800,14 @@ pub fn trans_log_level(bcx: @mut Block) -> DatumBlock { let ccx = bcx.ccx(); let (modpath, modname) = { - let path = &mut bcx.fcx.path; - let mut modpath = ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))]; - for e in path.iter() { + let srccrate = match ccx.external_srcs.find(&bcx.fcx.id) { + Some(&src) => { + cstore::get_crate_data(ccx.sess.cstore, src.crate).name + } + None => ccx.link_meta.name, + }; + let mut modpath = ~[path_mod(ccx.sess.ident_of(srccrate))]; + for e in bcx.fcx.path.iter() { match *e { path_mod(_) => { modpath.push(*e) } _ => {} diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 7cc1943a453..aa1ec26d426 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -197,9 +197,6 @@ pub fn describe_debug_flags() { } pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) { - // Don't display log spew by default. Can override with RUST_LOG. - ::std::logging::console_off(); - let mut args = args.to_owned(); let binary = args.shift().to_managed(); diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs index 27a2af95a2a..5e1ef3658b3 100644 --- a/src/libstd/logging.rs +++ b/src/libstd/logging.rs @@ -8,40 +8,101 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Logging +/*! + +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 4 +* `info!(...)` - a macro hard-wired to the log level of 3 +* `warn!(...)` - a macro hard-wired to the log level of 2 +* `error!(...)` - a macro hard-wired to the log level of 1 + +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 + +## 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: + +``` +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: + +``` +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::hashmap // turns on hello, and std's hashmap 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 +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 option::*; -use os; -use rt; +use rt::local::Local; use rt::logging::{Logger, StdErrLogger}; +use rt::task::Task; -/// Turns on logging to stdout globally -pub fn console_on() { - rt::logging::console_on(); -} - -/** - * Turns off logging to stdout globally - * - * Turns off the console unless the user has overridden the - * runtime environment's logging spec, e.g. by setting - * the RUST_LOG environment variable - */ -pub fn console_off() { - // If RUST_LOG is set then the console can't be turned off - if os::getenv("RUST_LOG").is_some() { - return; - } - - rt::logging::console_off(); -} - -#[allow(missing_doc)] +/// 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) { - use rt::task::Task; - use rt::local::Local; - unsafe { let optional_task: Option<*mut Task> = Local::try_unsafe_borrow(); match optional_task { diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs index 8b8e2762381..b08e76921d8 100644 --- a/src/libstd/rt/logging.rs +++ b/src/libstd/rt/logging.rs @@ -10,7 +10,7 @@ use fmt; use from_str::from_str; -use libc::{uintptr_t, exit}; +use libc::exit; use option::{Some, None, Option}; use rt; use rt::util::dumb_println; @@ -174,9 +174,7 @@ pub struct StdErrLogger; impl Logger for StdErrLogger { fn log(&mut self, args: &fmt::Arguments) { - if should_log_console() { - fmt::writeln(self as &mut rt::io::Writer, args); - } + fmt::writeln(self as &mut rt::io::Writer, args); } } @@ -222,21 +220,6 @@ pub fn init() { } } -#[fixed_stack_segment] #[inline(never)] -pub fn console_on() { unsafe { rust_log_console_on() } } - -#[fixed_stack_segment] #[inline(never)] -pub fn console_off() { unsafe { rust_log_console_off() } } - -#[fixed_stack_segment] #[inline(never)] -fn should_log_console() -> bool { unsafe { rust_should_log_console() != 0 } } - -extern { - fn rust_log_console_on(); - fn rust_log_console_off(); - fn rust_should_log_console() -> uintptr_t; -} - // Tests for parse_logging_spec() #[test] fn parse_logging_spec_valid() { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index d1d4286a7c6..13fc3f1aa81 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -320,27 +320,6 @@ rust_mktime(rust_tm* timeptr) { return mktime(&t); } -static lock_and_signal log_lock; -static bool log_to_console = true; - -extern "C" CDECL void -rust_log_console_on() { - scoped_lock with(log_lock); - log_to_console = true; -} - -extern "C" CDECL void -rust_log_console_off() { - scoped_lock with(log_lock); - log_to_console = false; -} - -extern "C" CDECL uintptr_t -rust_should_log_console() { - scoped_lock with(log_lock); - return log_to_console; -} - extern "C" lock_and_signal* rust_create_little_lock() { return new lock_and_signal(); diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 30f60c662e9..959d1fa85f3 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -17,9 +17,6 @@ rust_get_stderr rust_list_dir_val rust_list_dir_wfd_size rust_list_dir_wfd_fp_buf -rust_log_console_on -rust_log_console_off -rust_should_log_console rust_unset_sigprocmask rust_env_pairs rust_win32_rand_acquire diff --git a/src/test/auxiliary/logging_right_crate.rs b/src/test/auxiliary/logging_right_crate.rs new file mode 100644 index 00000000000..84bf6f0240f --- /dev/null +++ b/src/test/auxiliary/logging_right_crate.rs @@ -0,0 +1,14 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() { + fn death() -> int { fail2!() } + debug2!("{:?}", (||{ death() })()); +} diff --git a/src/test/run-pass/logging-right-crate.rs b/src/test/run-pass/logging-right-crate.rs new file mode 100644 index 00000000000..21b45cec235 --- /dev/null +++ b/src/test/run-pass/logging-right-crate.rs @@ -0,0 +1,30 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:logging_right_crate.rs +// xfail-fast +// exec-env:RUST_LOG=logging-right-crate=debug + +// This is a test for issue #3046 to make sure that when we monomorphize a +// function from one crate to another the right top-level logging name is +// preserved. +// +// It used to be the case that if logging were turned on for this crate, all +// monomorphized functions from other crates had logging turned on (their +// logging module names were all incorrect). This test ensures that this no +// longer happens by enabling logging for *this* crate and then invoking a +// function in an external crate which will fail when logging is enabled. + +extern mod logging_right_crate; + +fn main() { + // this function fails if logging is turned on + logging_right_crate::foo::(); +}