Skip to content

Commit a6dfdfe

Browse files
committed
refactor: finish initial flow preloader generalization for rr+db; fix for location
for now working in simple cases for db-backend, and at least not crashing for some for rr; but not yet a good example of working for rr; a small fix that tries to repeat the function first/last info for each of the lines in range in expr_loader; maybe we can instead check the region but for now hopefully an ok fix IMPORTANT: some problems overally: jumps and some flow in db-backend seem to be broken
1 parent 654d7ba commit a6dfdfe

File tree

9 files changed

+132
-82
lines changed

9 files changed

+132
-82
lines changed

src/db-backend/src/dap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pub fn to_json(message: &DapMessage) -> DapResult<String> {
371371
pub fn read_dap_message_from_reader<R: std::io::BufRead>(reader: &mut R) -> DapResult<DapMessage> {
372372
use log::info;
373373

374-
info!("from_reader");
374+
info!("read_dap_message_from_reader");
375375
let mut header = String::new();
376376
reader.read_line(&mut header).map_err(|e| {
377377
use log::error;

src/db-backend/src/db.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ impl Db {
261261
}
262262

263263
fn to_ct_type(&self, type_id: &TypeId) -> Type {
264+
if self.types.len() == 0 { // probably rr trace case
265+
warn!("to_ct_type: for now returning just a placeholder type: assuming rr trace!");
266+
return Type::new(TypeKind::None, "<None>");
267+
}
264268
let type_record = &self.types[*type_id];
265269
match self.types[*type_id].kind {
266270
TypeKind::Struct => {

src/db-backend/src/diff.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub fn index_diff(diff: Diff, trace_folder: &Path, multitrace_folder: &Path) ->
146146

147147
info!("diff_lines {diff_lines:?}");
148148
let mut flow_preloader = FlowPreloader::new();
149-
let mut replay = Box::new(DbReplay::new(db.clone()));
149+
let mut replay = DbReplay::new(Box::new(db.clone()));
150150
let flow_update = flow_preloader.load_diff_flow(diff_lines, &db, &mut replay);
151151

152152
let raw = serde_json::to_string(&flow_update)?;

src/db-backend/src/expr_loader.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::{
2-
db::DbStep,
32
lang::Lang,
43
task::{
54
Branch, BranchId, BranchState, CoreTrace, Location, LoopShape, LoopShapeId, Position, NO_BRANCH_ID, NO_POSITION,
@@ -276,13 +275,15 @@ impl ExprLoader {
276275
// extract function names and positions
277276
} else if NODE_NAMES[&lang].functions.contains(&node.kind().to_string()) {
278277
if let Some(name) = self.get_method_name(node, path, row) {
279-
self.processed_files
280-
.get_mut(path)
281-
.unwrap()
282-
.functions
283-
.entry(start)
284-
.or_default()
285-
.push((name.to_string(), start, end));
278+
for i in start.0 .. end.0 {
279+
self.processed_files
280+
.get_mut(path)
281+
.unwrap()
282+
.functions
283+
.entry(Position(i))
284+
.or_default()
285+
.push((name.to_string(), start, end));
286+
};
286287
self.loop_index = 1;
287288
}
288289
} else if NODE_NAMES[&lang].loops.contains(&node.kind().to_string()) && start != end {
@@ -384,7 +385,7 @@ impl ExprLoader {
384385

385386
pub fn load_branch_for_position(&self, position: Position, path: &PathBuf) -> HashMap<usize, BranchState> {
386387
let mut results: HashMap<usize, BranchState> = HashMap::default();
387-
if self.processed_files[path].position_branches.contains_key(&position) {
388+
if self.processed_files.contains_key(path) && self.processed_files[path].position_branches.contains_key(&position) {
388389
let mut branch = self.processed_files[path].position_branches[&position].clone();
389390
branch.status = BranchState::Taken;
390391
results.insert(branch.header_line.0 as usize, branch.status);
@@ -404,9 +405,11 @@ impl ExprLoader {
404405
check_list: &HashMap<usize, BranchState>,
405406
) -> HashMap<usize, BranchState> {
406407
let mut results: HashMap<usize, BranchState> = HashMap::default();
407-
for branch in &self.processed_files[path].branch {
408-
if !check_list.contains_key(&(branch.header_line.0 as usize)) && branch.status == BranchState::Unknown {
409-
results.insert(branch.header_line.0 as usize, BranchState::NotTaken);
408+
if self.processed_files.contains_key(path) {
409+
for branch in &self.processed_files[path].branch {
410+
if !check_list.contains_key(&(branch.header_line.0 as usize)) && branch.status == BranchState::Unknown {
411+
results.insert(branch.header_line.0 as usize, BranchState::NotTaken);
412+
}
410413
}
411414
}
412415
results
@@ -416,10 +419,10 @@ impl ExprLoader {
416419
info!("path {}", path.display());
417420
info!(
418421
"get_loop_shape {} {:?}",
419-
line.0, self.processed_files[path].position_loops
422+
line.0, self.processed_files.get(path)?.position_loops
420423
);
421-
if let Some(loop_shape_id) = self.processed_files[path].position_loops.get(&line) {
422-
return Some(self.processed_files[path].loop_shapes[loop_shape_id.0 as usize].clone());
424+
if let Some(loop_shape_id) = self.processed_files.get(path)?.position_loops.get(&line) {
425+
return Some(self.processed_files.get(path)?.loop_shapes[loop_shape_id.0 as usize].clone());
423426
}
424427
None
425428
}
@@ -486,6 +489,8 @@ impl ExprLoader {
486489
}
487490

488491
pub fn get_first_last_fn_lines(&self, location: &Location, line: &Line) -> (i64, i64) {
492+
info!("functions {:?}", self.processed_files);
493+
info!("get_first_last_fn_lines {:?}:{}", location.path, line.0);
489494
let (_, mut start, mut end): (String, Position, Position) =
490495
(String::default(), Position(NO_POSITION), Position(NO_POSITION));
491496
let path_buf = &PathBuf::from(&location.path);
@@ -517,15 +522,15 @@ impl ExprLoader {
517522
updated_location
518523
}
519524

520-
pub fn get_expr_list(&self, line: Line, location: &Location) -> Option<Vec<String>> {
525+
pub fn get_expr_list(&self, line: Position, location: &Location) -> Option<Vec<String>> {
521526
self.processed_files
522527
.get(&PathBuf::from(&location.path))
523-
.and_then(|file| file.variables.get(&Position(line.0)).cloned())
528+
.and_then(|file| file.variables.get(&line).cloned())
524529
}
525530
// pub fn load_loops(&mut self, )
526531

527532
pub fn get_comment_positions(&self, path: &PathBuf) -> Vec<Position> {
528-
self.processed_files.get(path).unwrap().comment_lines.clone()
533+
self.processed_files.get(path).unwrap_or(&FileInfo::new("")).comment_lines.clone()
529534
}
530535
}
531536

src/db-backend/src/flow_preloader.rs

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
use crate::{
2-
db::{Db, DbRecordEvent, DbStep},
2+
db::{Db, DbRecordEvent},
33
expr_loader::ExprLoader,
44
task::{
5-
self,
65
Action, BranchesTaken, CoreTrace, FlowEvent, FlowStep, FlowUpdate, FlowUpdateState, FlowUpdateStateKind,
76
FlowMode, FlowViewUpdate, Iteration, Location, Loop, LoopId, LoopIterationSteps, Position, RRTicks, StepCount
87
},
98
replay::Replay,
109
value::Value,
1110
};
1211
use log::{info, warn, error};
13-
use runtime_tracing::{CallKey, FullValueRecord, Line, StepId};
12+
use runtime_tracing::{CallKey, Line, StepId, ValueRecord, TypeId};
1413
use std::collections::{HashMap, HashSet};
1514
use std::path::PathBuf;
1615
use std::error::Error;
@@ -34,7 +33,7 @@ impl FlowPreloader {
3433
match self.expr_loader.load_file(&path_buf) {
3534
Ok(_) => {
3635
info!("Expression loader complete!");
37-
let mut call_flow_preloader: CallFlowPreloader = CallFlowPreloader::new(self, location, HashSet::new(), HashSet::new(), mode);
36+
let mut call_flow_preloader: CallFlowPreloader = CallFlowPreloader::new(self, location.clone(), HashSet::new(), HashSet::new(), mode);
3837
call_flow_preloader.load_flow(location, replay)
3938
}
4039
Err(e) => {
@@ -71,15 +70,15 @@ impl FlowPreloader {
7170
}
7271

7372
let mut call_flow_preloader = CallFlowPreloader::new(self, Location::default(), diff_lines, diff_call_keys, FlowMode::Diff);
74-
let location = Location { line: Line(1), ..Location::default() };
73+
let location = Location { line: 1, ..Location::default() };
7574
call_flow_preloader.load_flow(location, replay)
7675
}
7776

7877
// fn load_file(&mut self, path: &str) {
7978
// self.expr_loader.load_file(&PathBuf::from(path.to_string())).unwrap();
8079
// }
8180

82-
pub fn get_var_list(&self, line: Line, location: &Location) -> Option<Vec<String>> {
81+
pub fn get_var_list(&self, line: Position, location: &Location) -> Option<Vec<String>> {
8382
self.expr_loader.get_expr_list(line, location)
8483
}
8584

@@ -163,18 +162,21 @@ impl<'a> CallFlowPreloader<'a> {
163162
}
164163
}
165164

166-
fn add_return_value(&mut self, mut flow_view_update: FlowViewUpdate, replay: &mut dyn Replay, call_key: CallKey) -> FlowViewUpdate {
165+
fn add_return_value(&mut self, mut flow_view_update: FlowViewUpdate, replay: &mut dyn Replay) -> FlowViewUpdate {
166+
// assumes that replay is stopped on the place where return value is available
167+
168+
let return_string = "return".to_string();
169+
167170
// The if condition ensures, that the Options on which .unwrap() is called
168171
// are never None, so it is safe to unwrap them.
169-
let return_string = "return".to_string();
170172
if !flow_view_update.steps.is_empty() {
171173

172-
let db = Db::new(PathBuf::from("")); // we don't need its state for to_ct_value
174+
let db = Db::new(&PathBuf::from("")); // we don't need its state for to_ct_value
173175
let return_value_record = replay.load_return_value().unwrap_or(ValueRecord::Error {
174176
msg: "<return value error>".to_string(),
175177
type_id: TypeId(0),
176178
});
177-
let return_value = db.to_ct_value(return_value_record);
179+
let return_value = db.to_ct_value(&return_value_record);
178180

179181
#[allow(clippy::unwrap_used)]
180182
flow_view_update.steps.last_mut().unwrap().before_values.insert(
@@ -207,7 +209,7 @@ impl<'a> CallFlowPreloader<'a> {
207209
flow_view_update
208210
}
209211

210-
fn next_diff_flow_step(&self, from_step_id: StepId, including_from: bool, replay: &mut dyn Replay) -> (StepId, bool) {
212+
fn next_diff_flow_step(&self, _from_step_id: StepId, _including_from: bool, _replay: &mut dyn Replay) -> (StepId, bool) {
211213
// TODO: maybe combination of replay.next, diff_call_keys check, different for cases?s
212214
//
213215
// if from_step_id.0 >= db.steps.len() as i64 {
@@ -233,12 +235,12 @@ impl<'a> CallFlowPreloader<'a> {
233235
todo!()
234236
}
235237

236-
fn move_to_first_step(&self, from_step_id: StepId, replay: &mut dyn Replay) -> (StepId, bool) {
238+
fn move_to_first_step(&self, from_step_id: StepId, replay: &mut dyn Replay) -> Result<(StepId, bool), Box<dyn Error>> {
237239
let (step_id, progressing) = match self.mode {
238240
FlowMode::Call => (from_step_id, true),
239241
FlowMode::Diff => self.next_diff_flow_step(StepId(0), true, replay),
240242
};
241-
replay.jump_to(step_id);
243+
replay.jump_to(step_id)?;
242244
Ok((step_id, progressing))
243245
}
244246

@@ -248,7 +250,8 @@ impl<'a> CallFlowPreloader<'a> {
248250
// let step_to_different_line = true; // for flow for now makes sense to try to always reach a new line
249251
// db.next_step_id_relative_to(from_step_id, true, step_to_different_line),
250252
replay.step(Action::Next, true).unwrap(); // TODO: handle error
251-
let location = replay.load_location(&mut self.flow_preloader.expr_loader).unwrap(); // TODO: handle error
253+
let mut expr_loader = ExprLoader::new(CoreTrace::default());
254+
let location = replay.load_location(&mut expr_loader).unwrap(); // TODO: handle error
252255
let new_step_id = StepId(location.rr_ticks.0);
253256
let progressing = new_step_id != from_step_id;
254257
(new_step_id, progressing)
@@ -257,23 +260,23 @@ impl<'a> CallFlowPreloader<'a> {
257260
}
258261
}
259262

260-
fn call_key_from(&self, location: Location) -> Result<CallKey, Box<dyn Error>> {
263+
fn call_key_from(&self, location: &Location) -> Result<CallKey, Box<dyn Error>> {
261264
Ok(CallKey(location.key.parse::<i64>()?)) // for now still assume it's an integer
262265
}
263266

264267
fn load_view_update(&mut self, replay: &mut dyn Replay) -> Result<FlowViewUpdate, Box<dyn Error>> {
265268
// let start_step_id = StepId(self.location.rr_ticks.0);
266269
// db.calls[call_key].step_id;
267270
// let mut path_buf = &PathBuf::from(&self.location.path);
268-
let mut iter_step_id = StepId(self.location.rrTicks.0);
271+
let mut iter_step_id = StepId(self.location.rr_ticks.0);
269272
let mut flow_view_update = FlowViewUpdate::new(self.location.clone());
270273
let mut step_count = 0;
271274
let mut first = true;
272-
let last_call_key_result = self.call_key_from(self.location);
273-
let mut last_call_key = CallKey(0);
274-
match last_call_key_result {
275+
let tracked_call_key_result = self.call_key_from(&self.location);
276+
let tracked_call_key; // = CallKey(0);
277+
match tracked_call_key_result {
275278
Ok(call_key) => {
276-
last_call_key = call_key;
279+
tracked_call_key = call_key;
277280
},
278281
Err(e) => {
279282
error!("call key parse error: {e:?}");
@@ -291,15 +294,15 @@ impl<'a> CallFlowPreloader<'a> {
291294
// };
292295
let (step_id, progressing) = if first {
293296
first = false;
294-
self.move_to_first_step(iter_step_id, replay);
297+
self.move_to_first_step(iter_step_id, replay)?
295298
} else {
296-
self.move_to_next_step(iter_step_id, replay);
299+
self.move_to_next_step(iter_step_id, replay)
297300
};
298301

299302
iter_step_id = step_id;
300303
let mut expr_loader = ExprLoader::new(CoreTrace::default());
301-
self.location = replay.load_location(&mut expr_loader);
302-
let new_call_key = match self.call_key_from(self.location) {
304+
self.location = replay.load_location(&mut expr_loader)?;
305+
let new_call_key = match self.call_key_from(&self.location) {
303306
Ok(call_key) => {
304307
call_key
305308
}
@@ -309,8 +312,20 @@ impl<'a> CallFlowPreloader<'a> {
309312
}
310313
};
311314

312-
if self.mode == FlowMode::Call && last_call_key != new_call_key || !progressing {
313-
flow_view_update = self.add_return_value(flow_view_update, replay, call_key);
315+
if self.mode == FlowMode::Call && tracked_call_key != new_call_key || !progressing {
316+
replay.step(Action::StepIn, false)?; // hopefully go back to the end of our original function
317+
let return_location = replay.load_location(&mut expr_loader)?;
318+
let mut load_return_value = false;
319+
// maybe this can be improved with a limited loop/jump to return/exit of call in the future
320+
if let Ok(return_call_key) = self.call_key_from(&return_location) {
321+
if return_call_key == tracked_call_key {
322+
flow_view_update = self.add_return_value(flow_view_update, replay);
323+
load_return_value = true;
324+
}
325+
}
326+
if !load_return_value {
327+
warn!("we can't load return value");
328+
}
314329
info!("break flow");
315330
break;
316331
}
@@ -333,8 +348,8 @@ impl<'a> CallFlowPreloader<'a> {
333348
flow_view_update.add_step_count(line, step_count);
334349
info!("process loops");
335350
let path_buf = &PathBuf::from(&self.location.path);
336-
flow_view_update = self.process_loops(flow_view_update.clone(), Position(self.location.line.0), replay.current_step_id(), path_buf, step_count);
337-
flow_view_update = self.log_expressions(flow_view_update.clone(), Position(self.location.0), replay, step_id);
351+
flow_view_update = self.process_loops(flow_view_update.clone(), Position(self.location.line), replay.current_step_id(), path_buf, step_count);
352+
flow_view_update = self.log_expressions(flow_view_update.clone(), Position(self.location.line), replay, step_id);
338353
step_count += 1;
339354
}
340355
let path_buf = &PathBuf::from(&self.location.path);
@@ -346,7 +361,7 @@ impl<'a> CallFlowPreloader<'a> {
346361
.expr_loader
347362
.final_branch_load(path_buf, &flow_view_update.branches_taken[0][0].table),
348363
);
349-
flow_view_update
364+
Ok(flow_view_update)
350365
}
351366

352367
#[allow(clippy::unwrap_used)]
@@ -358,7 +373,7 @@ impl<'a> CallFlowPreloader<'a> {
358373
path_buf: &PathBuf,
359374
step_count: i64,
360375
) -> FlowViewUpdate {
361-
if let Some(loop_shape) = self.flow_preloader.expr_loader.get_loop_shape(&line, path_buf) {
376+
if let Some(loop_shape) = self.flow_preloader.expr_loader.get_loop_shape(line, path_buf) {
362377
if loop_shape.first.0 == line.0 && !self.active_loops.contains(&loop_shape.first) {
363378
flow_view_update.loops.push(Loop {
364379
base: LoopId(loop_shape.loop_id.0),
@@ -418,14 +433,14 @@ impl<'a> CallFlowPreloader<'a> {
418433
.insert(line.0 as usize, step_count as usize);
419434
flow_view_update.add_branches(
420435
flow_view_update.loops.clone().last_mut().unwrap().base.0,
421-
self.flow_preloader.expr_loader.load_branch_for_position(&line, path_buf),
436+
self.flow_preloader.expr_loader.load_branch_for_position(line, path_buf),
422437
);
423438
}
424439
} else {
425440
flow_view_update.loop_iteration_steps[0][0]
426441
.table
427442
.insert(line.0 as usize, step_count as usize);
428-
flow_view_update.add_branches(0, self.flow_preloader.expr_loader.load_branch_for_position(&line, path_buf));
443+
flow_view_update.add_branches(0, self.flow_preloader.expr_loader.load_branch_for_position(line, path_buf));
429444
}
430445
flow_view_update
431446
}
@@ -479,12 +494,12 @@ impl<'a> CallFlowPreloader<'a> {
479494
// variable_map.insert(name.clone(), full_value_record);
480495
// }
481496

482-
if let Some(var_list) = self.flow_preloader.get_var_list(line.0, &self.location) {
497+
if let Some(var_list) = self.flow_preloader.get_var_list(line, &self.location) {
483498
info!("var_list {:?}", var_list.clone());
484499
for value_name in &var_list {
485500
if let Ok(value) = replay.load_value(value_name) {
486501
// if variable_map.contains_key(value_name) {
487-
let db = Db::new(PathBuf::from("")); // no state needed for to_ct_value
502+
let db = Db::new(&PathBuf::from("")); // no state needed for to_ct_value
488503
let ct_value = db.to_ct_value(&value);
489504
flow_view_update
490505
.steps
@@ -507,7 +522,7 @@ impl<'a> CallFlowPreloader<'a> {
507522
if variable_map.contains_key(variable) {
508523
flow_view_update.steps[index]
509524
.after_values
510-
.insert(variable.clone(), variable_map[variable]);
525+
.insert(variable.clone(), variable_map[variable].clone());
511526
}
512527
}
513528
}

0 commit comments

Comments
 (0)