From 980570e5f89bec17f301a37670dad7e2275ed307 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Thu, 28 Mar 2019 16:29:55 -0700 Subject: [PATCH 01/15] Add fatal macro --- src/macros.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/macros.rs b/src/macros.rs index b496cb8..b89e2db 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -7,6 +7,27 @@ // licenses, and is: // Copyright Ⓒ 2015 The Rust Project Developers +/// Log a message at the error level, flush the logger, and then use the same +/// message to panic. +/// +/// This will duplicate the message, once via the registered +/// logger, then again via stderr for the panic. Since this is a fatal +/// condition, duplication is of less concern than the risk of missing the +/// message. This will always `panic!`, even if no logger is configured, or if error +/// level messages aren't logged. +#[macro_export] +macro_rules! fatal { + ($($arg:tt)+) => ( + match format_args!($($arg)+) { + args => { + $crate::error!("{}", args); + $crate::log::logger().flush(); + panic!("{}", args); + } + } + ) +} + /// Log an expression and its value at any specified level. /// /// Logs with the optional or default (module path of use) target, specified From 952785f2d2a71426f564cdd35cafd1b60815636d Mon Sep 17 00:00:00 2001 From: David Kellum Date: Thu, 28 Mar 2019 16:45:35 -0700 Subject: [PATCH 02/15] Add tests of fatal macro --- Cargo.lock | 255 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 ++ test_2015/src/lib.rs | 12 ++ test_2018/src/lib.rs | 13 +++ tests/fatal.rs | 97 ++++++++++++++++ 5 files changed, 384 insertions(+) create mode 100644 tests/fatal.rs diff --git a/Cargo.lock b/Cargo.lock index 20a5cea..ce40068 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,47 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "autocfg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cfg-if" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.50" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lock_api" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.4.6" @@ -13,11 +50,181 @@ dependencies = [ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "owning_ref" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_jitter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "smallvec" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "tao-log" version = "0.2.0" dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -40,7 +247,55 @@ name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] +"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 501c460..926e3c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,9 @@ travis-ci = { repository="dekellum/tao-log" } [dependencies] log = { version = ">= 0.4.6, < 0.5" } +[dev-dependencies] +parking_lot = { version = ">= 0.7.1, < 0.8" } + [build-dependencies] version_check = { version=">=0.1.5, <0.2" } @@ -34,3 +37,7 @@ std = [ "log/std" ] [[test]] name = "log_v" harness = false + +[[test]] +name = "fatal" +harness = true diff --git a/test_2015/src/lib.rs b/test_2015/src/lib.rs index 5ff615a..91c116f 100644 --- a/test_2015/src/lib.rs +++ b/test_2015/src/lib.rs @@ -28,3 +28,15 @@ fn test_2015_logv_macros() { warnv!("prefix", "{:?}", v); assert!(errorv!(v)); } + +#[test] +#[should_panic] +fn test_2015_fatal_static_msg() { + fatal!("static fatal msg"); +} + +#[test] +#[should_panic] +fn test_2015_fatal_format_msg() { + fatal!("fmt {}", "failing"); +} diff --git a/test_2018/src/lib.rs b/test_2018/src/lib.rs index 0a1e984..8f3665d 100644 --- a/test_2018/src/lib.rs +++ b/test_2018/src/lib.rs @@ -5,6 +5,7 @@ // Exhaustively list all directly used macros, to test without any other // hidden helper macros in scope. #[cfg(test)] use tao_log::{ + fatal, log, log_enabled, trace, debug, info, warn, error, logv, @@ -34,3 +35,15 @@ fn test_2018_logv_macros() { warnv!("prefix", "{:?}", v); assert!(errorv!(v)); } + +#[test] +#[should_panic] +fn test_2018_fatal_static_msg() { + fatal!("static fatal msg"); +} + +#[test] +#[should_panic] +fn test_2018_fatal_format_msg() { + fatal!("fmt {}", "failing"); +} diff --git a/tests/fatal.rs b/tests/fatal.rs new file mode 100644 index 0000000..8ce2c39 --- /dev/null +++ b/tests/fatal.rs @@ -0,0 +1,97 @@ +//! Tests of fatal macro + +use std::cell::RefCell; +use std::sync::{Once, Arc}; + +use tao_log::*; +use log::{Log, Record, Metadata}; + +use parking_lot::{ReentrantMutex, ReentrantMutexGuard}; + +fn set_boxed_logger(logger: Box) -> Result<(), log::SetLoggerError> { + log::set_logger(unsafe { &*Box::into_raw(logger) }) +} + +struct State { + last_log: ReentrantMutex>>, +} + +impl State { + fn take(&self) -> Option { + self.last_log.lock().replace(None) + } + fn lock(&self) -> ReentrantMutexGuard>> { + self.last_log.lock() + } +} + +struct Logger(Arc); + +impl Log for Logger { + fn enabled(&self, _: &Metadata) -> bool { + true + } + + fn log(&self, record: &Record) { + let msg = format!("{}", record.args()); + self.0.last_log.lock().replace(Some(msg)); + eprintln!("{:5} {}", record.level(), record.args()); + } + + fn flush(&self) { + eprintln!("flushed!"); + } +} + +fn test_logger() -> Arc { + use log::LevelFilter; + static TEST_LOG_INIT: Once = Once::new(); + static mut LOG_STATE: Option> = None; + unsafe { + TEST_LOG_INIT.call_once(|| { + let s = Arc::new(State { + last_log: ReentrantMutex::new(RefCell::new(None)) + }); + LOG_STATE = Some(s.clone()); + set_boxed_logger(Box::new(Logger(s))).unwrap(); + log::set_max_level(LevelFilter::Debug); + }); + LOG_STATE.as_ref().unwrap().clone() + } +} + +struct StaticMsgCheck(Arc); + +impl Drop for StaticMsgCheck { + fn drop(&mut self) { + assert_eq!(self.0.take(), Some("static fatal msg".to_owned())); + } +} + +#[test] +#[should_panic] +fn fatal_static_msg() { + let s1 = test_logger(); + let s2 = s1.clone(); + let _test_guard = s1.lock(); + let _fr = StaticMsgCheck(s2); + fatal!("static fatal msg"); +} + +struct FormatMsgCheck(Arc); + +impl Drop for FormatMsgCheck { + fn drop(&mut self) { + assert_eq!(self.0.take(), Some("fmt fatal msg".to_owned())); + } +} + +#[test] +#[should_panic] +fn fatal_format_msg() { + let s1 = test_logger(); + let s2 = s1.clone(); + let _test_guard = s1.lock(); + let _fr = FormatMsgCheck(s2); + fatal!("fmt {} msg", "fatal".to_owned()); +} From 9531f3dee67ee8602aaf6fac90f4c2940f8ab1c7 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 06:15:05 -0700 Subject: [PATCH 03/15] rustdoc cosmetic --- src/macros.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index b89e2db..b132cf1 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -10,11 +10,11 @@ /// Log a message at the error level, flush the logger, and then use the same /// message to panic. /// -/// This will duplicate the message, once via the registered -/// logger, then again via stderr for the panic. Since this is a fatal -/// condition, duplication is of less concern than the risk of missing the -/// message. This will always `panic!`, even if no logger is configured, or if error -/// level messages aren't logged. +/// This will duplicate the message, once via the registered logger, then +/// again via stderr for the panic. Since this is a fatal condition, +/// duplication is of less concern than the risk of missing the message. This +/// will always `panic!`, even if no logger is configured, or if error level +/// messages aren't logged. #[macro_export] macro_rules! fatal { ($($arg:tt)+) => ( From 335df74c65ff5f9264537aea85d2d9ec8191572d Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 06:25:38 -0700 Subject: [PATCH 04/15] deduplicated lock rand deps --- Cargo.lock | 79 +++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce40068..10608a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,8 +24,17 @@ dependencies = [ ] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -73,7 +82,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -81,18 +90,17 @@ dependencies = [ [[package]] name = "rand" -version = "0.6.5" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -103,20 +111,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" -version = "0.4.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -124,7 +124,7 @@ name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -132,39 +132,29 @@ name = "rand_isaac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_jitter" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_os" -version = "0.1.3" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_pcg" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -172,7 +162,7 @@ name = "rand_xorshift" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -180,7 +170,7 @@ name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -271,22 +261,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3906503e80ac6cbcacb2c2973fa8e473f24d7e2747c8c92bb230c2441cad96b5" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +"checksum rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46fbd5550acf75b0c2730f5dd1873751daf9beb8f11b44027778fae50d7feca" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" From d14619c81d66d9e91a4d89a07c5a0bc9ed39e3b0 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 07:18:26 -0700 Subject: [PATCH 05/15] add lib rustdoc summary of fatal macro --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 7449cfb..5c74552 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,6 +59,9 @@ //! above `debug!` statement does not log, and the cost of formatting the //! message string is avoided. //! +//! To these formatting macros, _tao_log_ adds [`fatal!`](macro.fatal.html), +//! which logs at _error_ level, and uses the same message to `panic!`. +//! //! ### Testing for output //! //! The [`log_enabled!`](macro.log_enabled.html) macro may be used to From 5ca8ff28d7c90d74479778080518fae6746396fb Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 09:30:26 -0700 Subject: [PATCH 06/15] use set_boxed_logger if std for fatal test, avoid an unsafe block --- tests/fatal.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/fatal.rs b/tests/fatal.rs index 8ce2c39..4062dce 100644 --- a/tests/fatal.rs +++ b/tests/fatal.rs @@ -8,8 +8,12 @@ use log::{Log, Record, Metadata}; use parking_lot::{ReentrantMutex, ReentrantMutexGuard}; +#[cfg(feature = "std")] +use log::set_boxed_logger; + +#[cfg(not(feature = "std"))] fn set_boxed_logger(logger: Box) -> Result<(), log::SetLoggerError> { - log::set_logger(unsafe { &*Box::into_raw(logger) }) + log::set_logger(Box::leak(logger)) } struct State { From 4012fcc260eacac404c9b6244920255fe791d8ff Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 09:39:17 -0700 Subject: [PATCH 07/15] reduce unsafe scope in fatal test --- tests/fatal.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/fatal.rs b/tests/fatal.rs index 4062dce..23b5ff9 100644 --- a/tests/fatal.rs +++ b/tests/fatal.rs @@ -51,17 +51,15 @@ fn test_logger() -> Arc { use log::LevelFilter; static TEST_LOG_INIT: Once = Once::new(); static mut LOG_STATE: Option> = None; - unsafe { - TEST_LOG_INIT.call_once(|| { - let s = Arc::new(State { - last_log: ReentrantMutex::new(RefCell::new(None)) - }); - LOG_STATE = Some(s.clone()); - set_boxed_logger(Box::new(Logger(s))).unwrap(); - log::set_max_level(LevelFilter::Debug); + TEST_LOG_INIT.call_once(|| { + let s = Arc::new(State { + last_log: ReentrantMutex::new(RefCell::new(None)) }); - LOG_STATE.as_ref().unwrap().clone() - } + unsafe { LOG_STATE = Some(s.clone()); } + set_boxed_logger(Box::new(Logger(s))).unwrap(); + log::set_max_level(LevelFilter::Debug); + }); + unsafe { LOG_STATE.as_ref().unwrap().clone() } } struct StaticMsgCheck(Arc); From 1d17b104e74b4c1a0c8932a4bbbd67cf8fa8fd48 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 09:54:25 -0700 Subject: [PATCH 08/15] Add doctest for fatal --- src/macros.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index b132cf1..81feab3 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -11,10 +11,21 @@ /// message to panic. /// /// This will duplicate the message, once via the registered logger, then -/// again via stderr for the panic. Since this is a fatal condition, -/// duplication is of less concern than the risk of missing the message. This -/// will always `panic!`, even if no logger is configured, or if error level -/// messages aren't logged. +/// again via stderr for the panic (default handler). Since this is a fatal +/// and presumably serious condition, potential duplication is of less concern +/// than the risk of missing the message. This will always `panic!`, even if +/// no logger is configured, or if error level messages aren't logged. +/// +/// # Example +/// +/// ```rust,should_panic +/// # use std::time::{Duration, Instant}; +/// use tao_log::fatal; +/// +/// # let td = Duration::new(0, 100_000_000); +/// fatal!("shields compromised, core breach in {:?}!", td); +/// // ^1 -- error level message: shields compromised, core breach in 100ms! +/// // ^2 -- panic: shields compromised, core breach in 100ms! #[macro_export] macro_rules! fatal { ($($arg:tt)+) => ( From 620c468cb8132510c339f811f63fe0b3fa11558f Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 10:05:42 -0700 Subject: [PATCH 09/15] more eprint logging in fatal test --- tests/fatal.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fatal.rs b/tests/fatal.rs index 23b5ff9..43d2d0c 100644 --- a/tests/fatal.rs +++ b/tests/fatal.rs @@ -66,6 +66,7 @@ struct StaticMsgCheck(Arc); impl Drop for StaticMsgCheck { fn drop(&mut self) { + eprintln!("checker drop called!"); assert_eq!(self.0.take(), Some("static fatal msg".to_owned())); } } @@ -84,6 +85,7 @@ struct FormatMsgCheck(Arc); impl Drop for FormatMsgCheck { fn drop(&mut self) { + eprintln!("checker drop called!"); assert_eq!(self.0.take(), Some("fmt fatal msg".to_owned())); } } From 22f789a940796b9e3df172315978dac1903b4d7d Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 11:06:28 -0700 Subject: [PATCH 10/15] improve fatal summary rustdoc --- src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5c74552..892b8c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,8 +59,9 @@ //! above `debug!` statement does not log, and the cost of formatting the //! message string is avoided. //! -//! To these formatting macros, _tao_log_ adds [`fatal!`](macro.fatal.html), -//! which logs at _error_ level, and uses the same message to `panic!`. +//! To these formatted logging macros, _tao_log_ adds a +//! [`fatal!`](macro.fatal.html) macro, which logs at the _error_ level, and +//! then uses the same message to `panic!`. //! //! ### Testing for output //! From 5d35c0cbeade88127dc2e6c6fef9c15e22280168 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 11:21:01 -0700 Subject: [PATCH 11/15] implement target optional arg for fatal --- src/macros.rs | 28 ++++++++++++++++++++-------- tests/fatal.rs | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 81feab3..b7b2f17 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -28,15 +28,12 @@ /// // ^2 -- panic: shields compromised, core breach in 100ms! #[macro_export] macro_rules! fatal { + (target: $target:expr, $($arg:tt)+) => ( + $crate::__tao_fatal!($target, $($arg)+) + ); ($($arg:tt)+) => ( - match format_args!($($arg)+) { - args => { - $crate::error!("{}", args); - $crate::log::logger().flush(); - panic!("{}", args); - } - } - ) + $crate::__tao_fatal!(module_path!(), $($arg)+) + ); } /// Log an expression and its value at any specified level. @@ -111,6 +108,21 @@ macro_rules! tracev { ($($arg:tt)+) => ($crate::__tao_logv!($crate::log::Level::Trace, $($arg)+)) } +// Helper macro for `fatal!` +#[doc(hidden)] +#[macro_export] +macro_rules! __tao_fatal { + ($target:expr, $($arg:tt)+) => ( + match format_args!($($arg)+) { + args => { + $crate::error!(target: $target, "{}", args); + $crate::log::logger().flush(); + panic!("{}", args); + } + } + ); +} + // Helper macro for the -v macros, handling the permutations of optional // parameters. Note: The required level parameter is first here for // convenience of internal use with variable-args. diff --git a/tests/fatal.rs b/tests/fatal.rs index 43d2d0c..8ae8362 100644 --- a/tests/fatal.rs +++ b/tests/fatal.rs @@ -97,5 +97,5 @@ fn fatal_format_msg() { let s2 = s1.clone(); let _test_guard = s1.lock(); let _fr = FormatMsgCheck(s2); - fatal!("fmt {} msg", "fatal".to_owned()); + fatal!(target: "grim", "fmt {} msg", "fatal".to_owned()); } From 89e81857e5098b20a44d48c61a78c4a0b39d2d18 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 11:28:36 -0700 Subject: [PATCH 12/15] fatal test cosmetic --- tests/fatal.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/fatal.rs b/tests/fatal.rs index 8ae8362..8d2727e 100644 --- a/tests/fatal.rs +++ b/tests/fatal.rs @@ -3,14 +3,12 @@ use std::cell::RefCell; use std::sync::{Once, Arc}; -use tao_log::*; use log::{Log, Record, Metadata}; +#[cfg(feature = "std")] use log::set_boxed_logger; +use tao_log::fatal; use parking_lot::{ReentrantMutex, ReentrantMutexGuard}; -#[cfg(feature = "std")] -use log::set_boxed_logger; - #[cfg(not(feature = "std"))] fn set_boxed_logger(logger: Box) -> Result<(), log::SetLoggerError> { log::set_logger(Box::leak(logger)) From e50c4f32435307846c896d20cd888a49f7ce4990 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 12:18:42 -0700 Subject: [PATCH 13/15] change log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6935a3d..b94853b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ## 0.2.0 (TBD) +* Add new `fatal!` macro, which works just like `error!` plus `panic!` (#1) * Add a `std` feature pass-through for the _log_ crate's `std` feature. We use it for tests here. From 22c574eb50c8ee0d6bff294110900b954218c122 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 12:24:19 -0700 Subject: [PATCH 14/15] summary typo --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 892b8c5..424e78c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ //! above `debug!` statement does not log, and the cost of formatting the //! message string is avoided. //! -//! To these formatted logging macros, _tao_log_ adds a +//! To these formatted logging macros, _tao-log_ adds a //! [`fatal!`](macro.fatal.html) macro, which logs at the _error_ level, and //! then uses the same message to `panic!`. //! From eb7bff709f2271341dd245ae627507ae2217d5e6 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Fri, 29 Mar 2019 12:32:04 -0700 Subject: [PATCH 15/15] missed doctest end --- src/macros.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/macros.rs b/src/macros.rs index b7b2f17..d660499 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -26,6 +26,7 @@ /// fatal!("shields compromised, core breach in {:?}!", td); /// // ^1 -- error level message: shields compromised, core breach in 100ms! /// // ^2 -- panic: shields compromised, core breach in 100ms! +/// ``` #[macro_export] macro_rules! fatal { (target: $target:expr, $($arg:tt)+) => (