Skip to content

Commit

Permalink
fix(vm): child_threads must be traversed for all threads
Browse files Browse the repository at this point in the history
Fixes a memory unsafety issue where a child thread could be freed if it only existed as a `RootedThread`
  • Loading branch information
Marwes committed Nov 6, 2017
1 parent 287d21a commit eac571b
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 1 deletion.
4 changes: 4 additions & 0 deletions vm/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ impl<'s> WriteOnly<'s, str> {
pub struct Generation(i32);

impl Generation {
pub fn is_root(self) -> bool {
self.0 == 0
}

/// Returns a generation which compared to any normal generation is always younger.
pub fn disjoint() -> Generation {
Generation(-1)
Expand Down
2 changes: 1 addition & 1 deletion vm/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ impl Traverseable for Thread {
fn traverse(&self, gc: &mut Gc) {
self.traverse_fields_except_stack(gc);
self.context.lock().unwrap().stack.get_values().traverse(gc);
self.child_threads.read().unwrap().traverse(gc);
}
}

Expand Down Expand Up @@ -553,6 +552,7 @@ impl Thread {
self.global_state.traverse(gc);
self.roots.read().unwrap().traverse(gc);
self.rooted_values.read().unwrap().traverse(gc);
self.child_threads.read().unwrap().traverse(gc);
}

fn parent_threads(&self) -> RwLockWriteGuard<Vec<GcPtr<Thread>>> {
Expand Down
1 change: 1 addition & 0 deletions vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ impl GlobalVmState {
metadata: Metadata,
value: Value,
) -> Result<()> {
assert!(value.generation().is_root());
let mut env = self.env.write().unwrap();
let globals = &mut env.globals;
let global = Global {
Expand Down

0 comments on commit eac571b

Please sign in to comment.