Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracing #244

Merged
merged 51 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ab96784
Refactor tracing
MarcelGarus Oct 4, 2022
2bf4012
Display stack traces
MarcelGarus Oct 4, 2022
c7499ba
Make cloning to other heap cheaper
MarcelGarus Oct 4, 2022
475ec6d
Improve stack trace formatting
MarcelGarus Oct 4, 2022
9a25969
Trace needs
MarcelGarus Oct 4, 2022
8087055
Format stack traces spanning multiple fibers
MarcelGarus Oct 5, 2022
add41fc
Move tracer into its own component
MarcelGarus Oct 5, 2022
316fe76
Revert " Move tracer into its own component"
MarcelGarus Oct 5, 2022
61ab412
Add responsibility to VM
MarcelGarus Oct 7, 2022
a2553d8
Fix fault attribution
MarcelGarus Oct 7, 2022
80fde35
Adapt fuzzing to new tracing
MarcelGarus Oct 10, 2022
9de29ee
Update todos
MarcelGarus Oct 13, 2022
8bf3321
Print to stdout using channels
MarcelGarus Oct 13, 2022
1885315
Merge branch 'channels' into tracing
MarcelGarus Oct 13, 2022
7ddf44c
Fix ids
MarcelGarus Oct 13, 2022
6c07c6f
Update fuzzing to responsibilites
MarcelGarus Oct 17, 2022
80f7b7c
Fix responsibilities of curly closures
MarcelGarus Oct 17, 2022
42673b9
Fix language server
MarcelGarus Oct 17, 2022
1b25bbf
Fix some lints
MarcelGarus Oct 17, 2022
f2c848a
Remove logging all stack traces
MarcelGarus Oct 17, 2022
1b51a94
Remove let_else feature flag
MarcelGarus Oct 17, 2022
734154a
Merge branch 'channels' into tracing
MarcelGarus Oct 17, 2022
5686ac0
Fix Clippy lints
MarcelGarus Oct 17, 2022
bd04d47
Merge branch 'channels' into tracing
MarcelGarus Oct 23, 2022
8f2dfff
Merge branch 'main' into tracing
MarcelGarus Oct 29, 2022
925e679
Merge branch 'main' into tracing
MarcelGarus Oct 29, 2022
11669c1
Implement some suggestions
MarcelGarus Oct 29, 2022
1d83364
Merge branch 'tracing' of https://github.com/candy-lang/candy into tr…
MarcelGarus Oct 29, 2022
7ef6394
Apply suggestions from code review
MarcelGarus Oct 29, 2022
46f01ba
Update compiler/src/vm/fiber.rs
MarcelGarus Oct 29, 2022
16d9537
Update compiler/src/vm/fiber.rs
MarcelGarus Oct 29, 2022
a102000
Restructure tracing
MarcelGarus Oct 29, 2022
182e550
Merge branch 'tracing' of https://github.com/candy-lang/candy into tr…
MarcelGarus Oct 29, 2022
4544a72
Fix indentation
MarcelGarus Oct 29, 2022
919608d
Pad stack trace strings to width
MarcelGarus Oct 29, 2022
dfaaa03
Make UseProvider non-mut
MarcelGarus Oct 29, 2022
3295ce8
Add assert in complete_try
MarcelGarus Oct 29, 2022
9e61013
Restructure tracing (again)
MarcelGarus Oct 30, 2022
36bce9c
Improve tracing of finishing fibers
MarcelGarus Oct 30, 2022
6699e3b
Remove unused events
MarcelGarus Oct 30, 2022
ce36027
Fix clippy lints
MarcelGarus Oct 30, 2022
5f4b696
Update compiler/src/vm/tracer/mod.rs
MarcelGarus Oct 30, 2022
8a9b492
Update compiler/src/vm/tracer/mod.rs
MarcelGarus Oct 30, 2022
930b4d0
Update compiler/src/vm/tracer/full.rs
MarcelGarus Oct 30, 2022
939a5e8
Add Cargo workspace
MarcelGarus Oct 31, 2022
8584929
Move tracer methods
MarcelGarus Oct 31, 2022
2724256
Move tracer methods
MarcelGarus Oct 31, 2022
4644a95
Refactor tracer
MarcelGarus Oct 31, 2022
5ba00af
Format main
MarcelGarus Oct 31, 2022
35b5c3b
Update .gitignores and lock files
MarcelGarus Oct 31, 2022
09c9be4
Remove commented out code
MarcelGarus Oct 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ notify = "4.0.17"
num-bigint = { version = "0.4.3", features = ["rand"] }
num-integer = { version = "0.1.45", features = ["i128"] }
num-traits = { version = "0.2.15", features = ["i128"] }
pad = "0.1.6"
proptest = "1.0.0"
rand = "0.8.5"
regex = "1.5.5"
Expand Down
1 change: 1 addition & 0 deletions compiler/src/compiler/hir_to_lir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl LoweringContext {
is_curly: bool,
) {
self.emit(Instruction::CreateClosure {
id: id.clone(),
captured,
num_args,
body: instructions,
Expand Down
4 changes: 3 additions & 1 deletion compiler/src/compiler/lir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum Instruction {
///
/// a -> a, pointer to closure
CreateClosure {
id: hir::Id,
captured: Vec<StackOffset>,
num_args: usize,
body: Vec<Instruction>,
Expand Down Expand Up @@ -137,14 +138,15 @@ impl Display for Instruction {
write!(f, "createStruct {num_entries}")
}
Instruction::CreateClosure {
id,
captured,
num_args,
body: instructions,
is_curly,
} => {
write!(
f,
"createClosure with {num_args} {} capturing {} {}",
"createClosure {id} with {num_args} {} capturing {} {}",
if *num_args == 1 {
"argument"
} else {
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/fuzzer/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
vm::{
self,
context::{ExecutionController, UseProvider},
tracer::FullTracer,
tracer::{full::FullTracer, Tracer},
Closure, Heap, Packet, Pointer, Vm,
},
};
Expand Down Expand Up @@ -57,7 +57,7 @@ impl Status {
Status::StillFuzzing {
vm,
arguments,
tracer: FullTracer::new(),
tracer: FullTracer::default(),
}
}
}
Expand Down Expand Up @@ -96,13 +96,13 @@ impl Fuzzer {
fn map_status<U: UseProvider, E: ExecutionController>(
&self,
status: Status,
use_provider: &mut U,
use_provider: &U,
execution_controller: &mut E,
) -> Status {
match status {
Status::StillFuzzing { mut vm, arguments, mut tracer } => match vm.status() {
vm::Status::CanRun => {
vm.run(use_provider, execution_controller, &mut tracer);
vm.run(use_provider, execution_controller, &mut tracer.for_vm());
Status::StillFuzzing { vm, arguments, tracer }
}
vm::Status::WaitingForOperations => panic!("Fuzzing should not have to wait on channel operations because arguments were not channels."),
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/fuzzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
module::Module,
vm::{
context::{DbUseProvider, RunForever, RunLimitedNumberOfInstructions},
tracer::Tracer,
Closure, Heap, Pointer, Vm,
},
};
Expand All @@ -20,10 +21,10 @@ use tracing::{error, info};

pub async fn fuzz(db: &Database, module: Module) {
let (fuzzables_heap, fuzzables): (Heap, Vec<(Id, Pointer)>) = {
let mut tracer = FuzzablesFinder::new();
let mut tracer = FuzzablesFinder::default();
let mut vm = Vm::new();
vm.set_up_for_running_module_closure(Closure::of_module(db, module).unwrap());
vm.run(&mut DbUseProvider { db }, &mut RunForever, &mut tracer);
vm.run(&DbUseProvider { db }, &mut RunForever, &mut tracer.for_vm());
(tracer.heap, tracer.fuzzables)
};

Expand Down
58 changes: 9 additions & 49 deletions compiler/src/fuzzer/utils.rs
Original file line number Diff line number Diff line change
@@ -1,72 +1,32 @@
use crate::{
compiler::hir::Id,
module::Module,
vm::{
tracer::{InFiberTracer, Tracer},
ChannelId, FiberId, Heap, Pointer,
tracer::{FiberEvent, Tracer, VmEvent},
FiberId, Heap, Pointer,
},
};
use std::collections::HashMap;

#[derive(Default)]
pub struct FuzzablesFinder {
pub fuzzables: Vec<(Id, Pointer)>,
pub heap: Heap,
transferred_objects: HashMap<FiberId, HashMap<Pointer, Pointer>>,
}
impl FuzzablesFinder {
pub fn new() -> Self {
Self {
fuzzables: vec![],
heap: Heap::default(),
transferred_objects: HashMap::new(),
}
}
}
impl Tracer for FuzzablesFinder {
fn fiber_created(&mut self, _fiber: FiberId) {}
fn fiber_done(&mut self, _fiber: FiberId) {}
fn fiber_panicked(&mut self, _fiber: FiberId, _panicked_child: Option<FiberId>) {}
fn fiber_canceled(&mut self, _fiber: FiberId) {}
fn fiber_execution_started(&mut self, _fiber: FiberId) {}
fn fiber_execution_ended(&mut self, _fiber: FiberId) {}
fn channel_created(&mut self, _channel: ChannelId) {}
fn sent_to_channel(&mut self, _value: Pointer, _from: FiberId, _to: ChannelId) {}
fn received_from_channel(&mut self, _value: Pointer, _from: ChannelId, _to: FiberId) {}

fn in_fiber_tracer<'a>(&'a mut self, fiber: FiberId) -> Box<dyn InFiberTracer<'a> + 'a>
where
Self: 'a,
{
Box::new(InFiberFuzzablesFinder {
tracer: self,
fiber,
})
}
}
pub struct InFiberFuzzablesFinder<'a> {
tracer: &'a mut FuzzablesFinder,
fiber: FiberId,
}
impl<'a> InFiberTracer<'a> for InFiberFuzzablesFinder<'a> {
fn module_started(&mut self, _module: Module) {}
fn module_ended(&mut self, _heap: &Heap, _export_map: Pointer) {}
fn value_evaluated(&mut self, _heap: &Heap, _id: Id, _value: Pointer) {}
fn call_started(&mut self, _heap: &Heap, _id: Id, _closure: Pointer, _args: Vec<Pointer>) {}
fn call_ended(&mut self, _heap: &Heap, _return_value: Pointer) {}
fn needs_started(&mut self, _heap: &Heap, _id: Id, _condition: Pointer, _reason: Pointer) {}
fn needs_ended(&mut self) {}
fn add(&mut self, event: VmEvent) {
let VmEvent::InFiber { fiber, event } = event else { return; };
let FiberEvent::FoundFuzzableClosure { id, closure, heap } = event else { return; };

fn found_fuzzable_closure(&mut self, heap: &Heap, id: Id, closure: Pointer) {
let address_map = self
.tracer
.transferred_objects
.entry(self.fiber)
.entry(fiber)
.or_insert_with(HashMap::new);
let address = heap.clone_single_to_other_heap_with_existing_mapping(
&mut self.tracer.heap,
&mut self.heap,
closure,
address_map,
);
self.tracer.fuzzables.push((id, address));
self.fuzzables.push((id, address));
}
}
19 changes: 12 additions & 7 deletions compiler/src/language_server/hints/constant_evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ use crate::{
vm::{
self,
context::{DbUseProvider, RunLimitedNumberOfInstructions},
tracer::{stack_trace::StackEntry, Event, FullTracer, InFiberEvent, TimedEvent},
tracer::{
full::{FullTracer, StoredFiberEvent, StoredVmEvent, TimedEvent},
stack_trace::StackEntry,
Tracer,
},
Closure, FiberId, Heap, Pointer, Vm,
},
};
Expand All @@ -32,7 +36,7 @@ struct Evaluator {

impl ConstantEvaluator {
pub fn update_module(&mut self, db: &Database, module: Module) {
let tracer = FullTracer::new();
let tracer = FullTracer::default();
let mut vm = Vm::new();
vm.set_up_for_running_module_closure(Closure::of_module(db, module.clone()).unwrap());
self.evaluators.insert(module, Evaluator { tracer, vm });
Expand All @@ -57,9 +61,9 @@ impl ConstantEvaluator {

if let Some((module, evaluator)) = running_evaluators.choose_mut(&mut thread_rng()) {
evaluator.vm.run(
&mut DbUseProvider { db },
&DbUseProvider { db },
&mut RunLimitedNumberOfInstructions::new(500),
&mut evaluator.tracer,
&mut evaluator.tracer.for_vm(),
);
Some(module.clone())
} else {
Expand All @@ -74,8 +78,8 @@ impl ConstantEvaluator {
.events
.iter()
.filter_map(|event| match &event.event {
Event::InFiber {
event: InFiberEvent::FoundFuzzableClosure { id, closure },
StoredVmEvent::InFiber {
event: StoredFiberEvent::FoundFuzzableClosure { id, closure },
..
} => Some((id.clone(), *closure)),
_ => None,
Expand All @@ -99,7 +103,8 @@ impl ConstantEvaluator {
};

for TimedEvent { event, .. } in &evaluator.tracer.events {
let Event::InFiber { event: InFiberEvent::ValueEvaluated { id, value }, .. } = event else { continue; };
let StoredVmEvent::InFiber { event, .. } = event else { continue; };
let StoredFiberEvent::ValueEvaluated { id, value } = event else { continue; };

if &id.module != module {
continue;
Expand Down
12 changes: 6 additions & 6 deletions compiler/src/language_server/hints/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
module::Module,
vm::{
context::{DbUseProvider, RunLimitedNumberOfInstructions},
tracer::{Event, InFiberEvent},
tracer::full::{StoredFiberEvent, StoredVmEvent},
Heap, Pointer,
},
};
Expand Down Expand Up @@ -111,13 +111,13 @@ impl FuzzerManager {
// Find the innermost panicking call that is in the
// function.
.filter_map(|event| match &event.event {
Event::InFiber { event, .. } => Some(event),
StoredVmEvent::InFiber { event, .. } => Some(event),
_ => None,
})
.find(|event| {
let innermost_panicking_call_id = match &event {
InFiberEvent::CallStarted { id, .. } => id,
InFiberEvent::NeedsStarted { id, .. } => id,
StoredFiberEvent::CallStarted { id, .. } => id,
StoredFiberEvent::NeedsStarted { id, .. } => id,
_ => return false,
};
id.is_same_module_and_any_parent_of(innermost_panicking_call_id)
Expand All @@ -133,10 +133,10 @@ impl FuzzerManager {
}
};
let (call_id, name, arguments) = match &panicking_inner_call {
InFiberEvent::CallStarted { id, closure, args } => {
StoredFiberEvent::CallStarted { id, closure, args } => {
(id.clone(), closure.format(&tracer.heap), args.clone())
}
InFiberEvent::NeedsStarted {
StoredFiberEvent::NeedsStarted {
id,
condition,
reason,
Expand Down
25 changes: 17 additions & 8 deletions compiler/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::{
module::{Module, ModuleKind},
vm::{
context::{DbUseProvider, RunForever},
tracer::{FullTracer, Tracer},
tracer::{full::FullTracer, Tracer},
Closure, ExecutionResult, FiberId, Status, Struct, Vm,
},
};
Expand Down Expand Up @@ -210,11 +210,15 @@ fn run(options: CandyRunOptions) {
debug!("Running `{path_string}`.");

let module_closure = Closure::of_module(&db, module.clone()).unwrap();
let mut tracer = FullTracer::new();
let mut tracer = FullTracer::default();

let mut vm = Vm::new();
vm.set_up_for_running_module_closure(module_closure);
vm.run(&mut DbUseProvider { db: &db }, &mut RunForever, &mut tracer);
vm.run(
&DbUseProvider { db: &db },
&mut RunForever,
&mut tracer.for_vm(),
);
if let Status::WaitingForOperations = vm.status() {
error!("The module waits on channel operations. Perhaps, the code tried to read from a channel without sending a packet into it.");
// TODO: Show stack traces of all fibers?
Expand Down Expand Up @@ -273,18 +277,22 @@ fn run(options: CandyRunOptions) {
let stdout_port = heap.create_send_port(stdout.channel);
heap.create_struct(HashMap::from([(stdout_symbol, stdout_port)]))
};
tracer.in_fiber_tracer(FiberId::root()).call_started(
&heap,
tracer.for_vm().for_fiber(FiberId::root()).call_started(
Id::new(module, vec!["main".to_string()]),
main,
vec![environment],
&heap,
);
vm.set_up_for_running_closure(heap, main, &[environment]);
loop {
match vm.status() {
Status::CanRun => {
debug!("VM still running.");
vm.run(&mut DbUseProvider { db: &db }, &mut RunForever, &mut tracer);
vm.run(
&DbUseProvider { db: &db },
&mut RunForever,
&mut tracer.for_vm(),
);
}
Status::WaitingForOperations => {
todo!("VM can't proceed until some operations complete.");
Expand All @@ -299,8 +307,9 @@ fn run(options: CandyRunOptions) {
match vm.tear_down() {
ExecutionResult::Finished(return_value) => {
tracer
.in_fiber_tracer(FiberId::root())
.call_ended(&return_value.heap, return_value.address);
.for_vm()
.for_fiber(FiberId::root())
.call_ended(return_value.address, &return_value.heap);
debug!("The main function returned: {return_value:?}");
}
ExecutionResult::Panicked {
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/vm/builtin_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use super::{
fiber::{Fiber, Status},
heap::{Closure, Data, Int, Pointer, ReceivePort, SendPort, Struct, Symbol, Text},
ids::ChannelId,
tracer::DummyInFiberTracer,
Heap,
tracer::{dummy::DummyTracer, Tracer},
FiberId, Heap,
};
use crate::{builtin_functions::BuiltinFunction, compiler::lir::Instruction};
use itertools::Itertools;
Expand Down Expand Up @@ -67,8 +67,8 @@ impl Fiber {
Ok(DivergeControlFlow { closure }) => {
self.data_stack.push(closure);
self.run_instruction(
&mut PanickingUseProvider,
&mut DummyInFiberTracer,
&PanickingUseProvider,
&mut DummyTracer.for_vm().for_fiber(FiberId::root()),
Instruction::Call { num_args: 0 },
);
}
Expand Down
Loading