Skip to content

Commit

Permalink
Panics now contains the panic info
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Aug 11, 2024
1 parent cb20d95 commit 53f491a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
10 changes: 7 additions & 3 deletions muse-lang/src/runtime/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub static LIST_TYPE: RustType<List> = RustType::new("List", |t| {
1,
|vm, this| {
let key = vm[Register(0)].take();
this.get(&key)
this.get_by_value(&key)
},
),
)
Expand All @@ -67,13 +67,17 @@ impl List {
///
/// Returns [`Fault::OutOfBounds`] if `index` cannot be converted to a
/// `usize` or is out of bounds of this list.
pub fn get(&self, index: &Value) -> Result<Value, Fault> {
pub fn get_by_value(&self, index: &Value) -> Result<Value, Fault> {
let Some(index) = index.as_usize() else {
return Err(Fault::OutOfBounds);
};
self.get(index).ok_or(Fault::OutOfBounds)
}

pub fn get(&self, index: usize) -> Option<Value> {
let contents = self.0.lock();

contents.get(index).copied().ok_or(Fault::OutOfBounds)
contents.get(index).copied()
}

/// Inserts `value` at `index`.
Expand Down
32 changes: 28 additions & 4 deletions muse-reactor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,17 @@
//! ```
#![allow(missing_docs)]
use std::any::Any;
use std::backtrace::Backtrace;
use std::cell::Cell;
use std::collections::VecDeque;
use std::fmt::Debug;
use std::fmt::{Debug, Write};
use std::future::Future;
use std::marker::PhantomData;
use std::num::NonZeroUsize;
use std::panic::{self, AssertUnwindSafe};
use std::panic::{self, AssertUnwindSafe, PanicInfo};
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::{Arc, OnceLock};
use std::task::{Context, Poll, Wake, Waker};
use std::thread::{self, JoinHandle};
use std::time::{Duration, Instant};
Expand Down Expand Up @@ -105,6 +106,11 @@ extern crate tracing;
#[macro_use]
mod mock_tracing;

static PANIC_HOOK_INSTALL: OnceLock<()> = OnceLock::new();
thread_local! {
static PANIC_INFO: Cell<Option<(String, Option<Backtrace>)>> = Cell::new(None);
}

pub struct Builder<Work> {
vm_source: Option<Arc<dyn NewVm<Work>>>,
threads: usize,
Expand Down Expand Up @@ -153,6 +159,14 @@ where
}

pub fn finish(self) -> ReactorHandle<Work> {
PANIC_HOOK_INSTALL.get_or_init(|| {
let default_hook = panic::take_hook();
panic::set_hook(Box::new(move |info: &PanicInfo| {
PANIC_INFO.set(Some((info.to_string(), Some(Backtrace::capture()))));
default_hook(info);
}));
});

let (sender, receiver) = if let Some(limit) = self.work_queue_limit {
flume::bounded(limit)
} else {
Expand Down Expand Up @@ -581,8 +595,18 @@ where
}
Err(mut panic) => {
drop(future);
let (mut summary, backtrace) = PANIC_INFO.take().unwrap_or_default();
if let Some(backtrace) = backtrace {
let _result = write!(&mut summary, "\n{backtrace}");
}
let result = root_result(
Err(Value::from(SymbolRef::from("panic"))),
Err(Value::dynamic(
List::from_iter([
Value::from(SymbolRef::from("panic")),
Value::from(SymbolRef::from(summary)),
]),
vm_context.guard(),
)),
&mut vm_context,
);
drop(vm_context);
Expand Down
12 changes: 10 additions & 2 deletions muse-reactor/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::time::{Duration, Instant};

use muse_lang::compiler::syntax::Ranged;
use muse_lang::compiler::{self};
use muse_lang::runtime::symbol::Symbol;
use muse_lang::runtime::list::List;
use muse_lang::runtime::symbol::SymbolRef;
use muse_lang::runtime::value::{Primitive, RootedValue, RustFunction, Value};
use muse_lang::vm::Vm;
use refuse::CollectionGuard;
Expand Down Expand Up @@ -204,7 +205,14 @@ fn task_panic() {
let task = reactor.spawn_source("panics()").unwrap();
let error = task.join().unwrap_err();
match error {
TaskError::Exception(exc) if exc == RootedValue::from(Symbol::from("panic")) => {}
TaskError::Exception(exc)
if exc.as_rooted::<List>().map_or(false, |list| {
list.get(0) == Some(Value::from(SymbolRef::from("panic")))
&& list
.get(1)
.and_then(|v| v.as_symbol(&CollectionGuard::acquire()))
.map_or(false, |s| dbg!(s).contains("panicked at muse-reactor"))
}) => {}
other => unreachable!("Unexpected result: {other:?}"),
}
}

0 comments on commit 53f491a

Please sign in to comment.