diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-08-28 01:33:48 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-09-25 16:30:05 -0700 |
| commit | eb2b25dd6d38157213742b048fad63fa4ceec691 (patch) | |
| tree | e41f9af78454e8f6641dead395274419d843ab63 /src/libstd/sys.rs | |
| parent | af25f58ac3da45899ed65b3af965150c8a90dcda (diff) | |
| download | rust-eb2b25dd6d38157213742b048fad63fa4ceec691.tar.gz rust-eb2b25dd6d38157213742b048fad63fa4ceec691.zip | |
Refactor the logging system for fewer allocations
This lifts various restrictions on the runtime, for example the character limit when logging a message. Right now the old debug!-style macros still involve allocating (because they use fmt! syntax), but the new debug2! macros don't involve allocating at all (unless the formatter for a type requires allocation.
Diffstat (limited to 'src/libstd/sys.rs')
| -rw-r--r-- | src/libstd/sys.rs | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index c315c3f9dfc..c38f3525867 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 <unnamed> 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("<unnamed>"); + 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", |
