Skip to content

Commit 966d626

Browse files
committed
feat: add a small abstraction for db & rr replays: try to support load_location for rr
1 parent 6fd3054 commit 966d626

File tree

7 files changed

+148
-47
lines changed

7 files changed

+148
-47
lines changed

src/db-backend/src/db.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
use num_bigint::BigInt;
22
use serde::{Deserialize, Serialize};
33
use std::collections::HashMap;
4+
use std::error::Error;
45
use std::path::PathBuf;
56
use std::vec::Vec;
67

7-
use crate::distinct_vec::DistinctVec;
8-
use crate::expr_loader::ExprLoader;
9-
use crate::lang::Lang;
10-
use crate::task::{Call, CallArg, Location, RRTicks};
11-
use crate::value::{Type, Value};
128
use log::{error, info, warn};
139
use runtime_tracing::{
1410
CallKey, EventLogKind, FullValueRecord, FunctionId, FunctionRecord, Line, PathId, Place, StepId, TypeId, TypeKind,
1511
TypeRecord, TypeSpecificInfo, ValueRecord, VariableId, NO_KEY,
1612
};
1713

14+
use crate::distinct_vec::DistinctVec;
15+
use crate::expr_loader::ExprLoader;
16+
use crate::lang::Lang;
17+
use crate::replay::Replay;
18+
use crate::task::{Call, CallArg, Location, RRTicks, NO_INDEX};
19+
use crate::value::{Type, Value};
20+
1821
const NEXT_INTERNAL_STEP_OVERS_LIMIT: usize = 1_000;
1922

20-
#[derive(Debug)]
23+
#[derive(Debug, Clone)]
2124
pub struct Db {
2225
pub workdir: PathBuf,
2326
pub functions: DistinctVec<FunctionId, FunctionRecord>,
@@ -769,3 +772,34 @@ pub enum EndOfProgram {
769772
// pub step_id: StepId,
770773
// pub place: Place,
771774
// }
775+
776+
#[derive(Debug)]
777+
pub struct DbReplay {
778+
pub db: Box<Db>,
779+
pub step_id: StepId,
780+
}
781+
782+
impl DbReplay {
783+
pub fn new(db: Box<Db>) -> DbReplay {
784+
DbReplay { db, step_id: StepId(0) }
785+
}
786+
787+
pub fn step_id_jump(&mut self, step_id: StepId) {
788+
if step_id.0 != NO_INDEX {
789+
self.step_id = step_id;
790+
}
791+
}
792+
}
793+
794+
impl Replay for DbReplay {
795+
fn load_location(&mut self, expr_loader: &mut ExprLoader) -> Result<Location, Box<dyn Error>> {
796+
info!("load_location: db replay");
797+
let call_key = self.db.call_key_for_step(self.step_id);
798+
Ok(self.db.load_location(self.step_id, call_key, expr_loader))
799+
}
800+
801+
fn run_to_entry(&mut self) -> Result<(), Box<dyn Error>> {
802+
self.step_id_jump(StepId(0));
803+
Ok(())
804+
}
805+
}

src/db-backend/src/handler.rs

Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ use runtime_tracing::{CallKey, EventLogKind, Line, PathId, StepId, VariableId, N
1010

1111
use crate::calltrace::Calltrace;
1212
use crate::dap::{self, DapClient, DapMessage};
13-
use crate::db::{Db, DbCall, DbRecordEvent, DbStep};
13+
use crate::db::{Db, DbCall, DbRecordEvent, DbReplay, DbStep};
1414
use crate::event_db::{EventDb, SingleTableId};
1515
use crate::expr_loader::ExprLoader;
1616
use crate::flow_preloader::FlowPreloader;
1717
use crate::program_search_tool::ProgramSearchTool;
18+
use crate::replay::Replay;
1819
use crate::rr_dispatcher::{CtRRArgs, RRDispatcher};
1920
// use crate::response::{};
2021
use crate::dap_types;
@@ -53,11 +54,13 @@ pub struct Handler {
5354
pub previous_step_id: StepId,
5455

5556
pub trace_kind: TraceKind,
56-
pub rr: RRDispatcher,
57+
// pub rr: RRDispatcher,
58+
pub replay: Box<dyn Replay>,
59+
5760
pub breakpoint_list: Vec<HashMap<usize, BreakpointRecord>>,
5861
}
5962

60-
#[derive(Debug, Clone)]
63+
#[derive(Debug, Clone, PartialEq)]
6164
pub enum TraceKind {
6265
DB,
6366
RR,
@@ -100,10 +103,15 @@ impl Handler {
100103
let mut breakpoint_list: Vec<HashMap<usize, BreakpointRecord>> = Default::default();
101104
breakpoint_list.resize_with(db.paths.len(), HashMap::new);
102105
let step_lines_loader = StepLinesLoader::new(&db, &mut expr_loader);
106+
let replay: Box<dyn Replay> = if trace_kind == TraceKind::DB {
107+
Box::new(DbReplay::new(db.clone()))
108+
} else {
109+
Box::new(RRDispatcher::new(ct_rr_args))
110+
};
103111
// let sender = sender::Sender::new();
104112
Handler {
105113
trace_kind,
106-
db,
114+
db: db.clone(),
107115
step_id: StepId(0),
108116
last_call_key: CallKey(0),
109117
indirect_send,
@@ -117,7 +125,8 @@ impl Handler {
117125
step_lines_loader,
118126
dap_client: DapClient::default(),
119127
previous_step_id: StepId(0),
120-
rr: RRDispatcher::new(ct_rr_args),
128+
// rr: RRDispatcher::new(ct_rr_args),
129+
replay,
121130
resulting_dap_messages: vec![],
122131
raw_diff_index: None,
123132
}
@@ -215,29 +224,28 @@ impl Handler {
215224
self.send_dap(&response)
216225
}
217226

218-
fn complete_move(&mut self, is_main: bool) -> Result<(), Box<dyn Error>> {
219-
let call_key = self.db.call_key_for_step(self.step_id);
220-
let reset_flow = is_main || call_key != self.last_call_key;
221-
self.last_call_key = call_key;
222-
info!("complete move: step_id: {:?}", self.step_id);
223-
let move_state = MoveState {
224-
status: "".to_string(),
225-
location: self.db.load_location(self.step_id, call_key, &mut self.expr_loader),
226-
c_location: Location::default(),
227-
main: is_main,
228-
reset_flow,
229-
stop_signal: RRGDBStopSignal::OtherStopSignal,
230-
frame_info: FrameInfo::default(),
231-
};
232-
233-
// info!("move_state {:?}", move_state);
227+
// will be sent after completion of query
228+
fn prepare_stopped_event(&mut self, is_main: bool) -> Result<(), Box<dyn Error>> {
234229
let reason = if is_main { "entry" } else { "step" };
235230
info!("generate stopped event");
236231
let raw_event = self.dap_client.stopped_event(reason)?;
237232
info!("raw stopped event: {:?}", raw_event);
238233
self.send_dap(&raw_event)?;
239-
let raw_complete_move_event = self.dap_client.complete_move_event(&move_state)?;
234+
Ok(())
235+
}
236+
237+
fn prepare_complete_move_event(&mut self, move_state: &MoveState) -> Result<(), Box<dyn Error>> {
238+
let raw_complete_move_event = self.dap_client.complete_move_event(move_state)?;
240239
self.send_dap(&raw_complete_move_event)?;
240+
Ok(())
241+
}
242+
243+
fn prepare_output_events(&mut self) -> Result<(), Box<dyn Error>> {
244+
if self.trace_kind == TraceKind::RR {
245+
warn!("prepare_output_events not implemented for rr");
246+
return Ok(()); // TODO
247+
}
248+
241249
if self.step_id.0 > self.previous_step_id.0 {
242250
let mut raw_output_events: Vec<dap::DapMessage> = vec![];
243251
for event in self.db.events.iter() {
@@ -264,9 +272,14 @@ impl Handler {
264272
self.send_dap(raw_output_event)?;
265273
}
266274
}
267-
self.previous_step_id = self.step_id;
275+
Ok(())
276+
}
268277

269-
// self.send_notification(NotificationKind::Success, "Complete move!", true)?;
278+
fn prepare_eventual_error_event(&mut self) -> Result<(), Box<dyn Error>> {
279+
if self.trace_kind == TraceKind::RR {
280+
warn!("prepare_eventual_error_event not implemented for rr");
281+
return Ok(()); // TODO
282+
}
270283

271284
let exact = false; // or for now try as flow // true just for this exact step
272285
let step_events = self.db.load_step_events(self.step_id, exact);
@@ -283,15 +296,44 @@ impl Handler {
283296
Ok(())
284297
}
285298

299+
fn complete_move(&mut self, is_main: bool) -> Result<(), Box<dyn Error>> {
300+
info!("complete_move");
301+
302+
// self.db.load_location(self.step_id, call_key, &mut self.expr_loader),
303+
let location = self.replay.load_location(&mut self.expr_loader)?;
304+
// let call_key = location.call_key; // self.db.call_key_for_step(self.step_id);
305+
// TODO: change if we need to support non-int keys
306+
let call_key = CallKey(location.key.parse::<i64>()?);
307+
let reset_flow = is_main || call_key != self.last_call_key;
308+
self.last_call_key = call_key;
309+
info!(" location: {location:?}");
310+
311+
let move_state = MoveState {
312+
status: "".to_string(),
313+
location,
314+
c_location: Location::default(),
315+
main: is_main,
316+
reset_flow,
317+
stop_signal: RRGDBStopSignal::OtherStopSignal,
318+
frame_info: FrameInfo::default(),
319+
};
320+
321+
self.prepare_stopped_event(is_main)?;
322+
self.prepare_complete_move_event(&move_state)?;
323+
self.prepare_output_events()?;
324+
325+
self.previous_step_id = self.step_id;
326+
327+
// self.send_notification(NotificationKind::Success, "Complete move!", true)?;
328+
329+
self.prepare_eventual_error_event()?;
330+
331+
Ok(())
332+
}
333+
286334
pub fn run_to_entry(&mut self, _req: dap::Request) -> Result<(), Box<dyn Error>> {
287-
match self.trace_kind {
288-
TraceKind::DB => {
289-
self.step_id_jump(StepId(0));
290-
}
291-
TraceKind::RR => {
292-
self.rr.run_to_entry()?;
293-
}
294-
}
335+
self.replay.run_to_entry()?;
336+
self.step_id = StepId(0); // TODO: use only db replay step_id or another workaround?
295337
self.complete_move(true)?;
296338
Ok(())
297339
}

src/db-backend/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub mod lang;
4040
pub mod paths;
4141
pub mod program_search_tool;
4242
pub mod query;
43+
pub mod replay;
4344
pub mod rr_dispatcher;
4445
pub mod step_lines_loader;
4546
pub mod task;

src/db-backend/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod lang;
3939
mod paths;
4040
mod program_search_tool;
4141
mod query;
42+
mod replay;
4243
mod rr_dispatcher;
4344
mod step_lines_loader;
4445
mod task;

src/db-backend/src/query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ use serde::{Deserialize, Serialize};
44
#[serde(tag = "kind")]
55
pub enum CtRRQuery {
66
RunToEntry,
7+
LoadLocation,
78
}

src/db-backend/src/replay.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use std::error::Error;
2+
3+
use crate::expr_loader::ExprLoader;
4+
use crate::task::Location;
5+
6+
pub trait Replay: std::fmt::Debug {
7+
fn load_location(&mut self, expr_loader: &mut ExprLoader) -> Result<Location, Box<dyn Error>>;
8+
fn run_to_entry(&mut self) -> Result<(), Box<dyn Error>>;
9+
}

src/db-backend/src/rr_dispatcher.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ use std::time::Duration;
99

1010
use log::info;
1111

12+
use crate::expr_loader::ExprLoader;
1213
use crate::paths::ct_rr_worker_socket_path;
1314
use crate::query::CtRRQuery;
15+
use crate::replay::Replay;
16+
use crate::task::Location;
1417

1518
#[derive(Debug)]
1619
pub struct RRDispatcher {
@@ -90,8 +93,8 @@ impl CtRRWorker {
9093
Ok(())
9194
}
9295

93-
// for now: don't return a typed value here, only ok or an error
94-
pub fn run_query(&mut self, query: CtRRQuery) -> Result<(), Box<dyn Error>> {
96+
// for now: don't return a typed value here, only Ok(raw value) or an error
97+
pub fn run_query(&mut self, query: CtRRQuery) -> Result<String, Box<dyn Error>> {
9598
let raw_json = serde_json::to_string(&query)?;
9699

97100
info!("send to worker {raw_json}\n");
@@ -110,8 +113,8 @@ impl CtRRWorker {
110113

111114
info!("res {res}");
112115

113-
if res == "ok" {
114-
Ok(())
116+
if !res.starts_with("error:") {
117+
Ok(res)
115118
} else {
116119
Err(format!("run_query ct rr worker error: {}", res).into())
117120
}
@@ -127,11 +130,6 @@ impl RRDispatcher {
127130
}
128131
}
129132

130-
pub fn run_to_entry(&mut self) -> Result<(), Box<dyn Error>> {
131-
self.ensure_active_stable()?;
132-
self.stable.run_query(CtRRQuery::RunToEntry)
133-
}
134-
135133
pub fn ensure_active_stable(&mut self) -> Result<(), Box<dyn Error>> {
136134
// start stable process if not active, store fields, setup ipc? store in stable
137135
if !self.stable.active {
@@ -145,3 +143,18 @@ impl RRDispatcher {
145143
Ok(())
146144
}
147145
}
146+
147+
impl Replay for RRDispatcher {
148+
fn load_location(&mut self, _expr_loader: &mut ExprLoader) -> Result<Location, Box<dyn Error>> {
149+
self.ensure_active_stable()?;
150+
Ok(serde_json::from_str::<Location>(
151+
&self.stable.run_query(CtRRQuery::LoadLocation)?,
152+
)?)
153+
}
154+
155+
fn run_to_entry(&mut self) -> Result<(), Box<dyn Error>> {
156+
self.ensure_active_stable()?;
157+
let _ok = self.stable.run_query(CtRRQuery::RunToEntry)?;
158+
Ok(())
159+
}
160+
}

0 commit comments

Comments
 (0)