Skip to content

Commit dbbfc30

Browse files
committed
feat: try to support callstack instead of calltrace for rr: for now
TODO: bugfixing and finish jumping
1 parent c76570e commit dbbfc30

File tree

7 files changed

+113
-34
lines changed

7 files changed

+113
-34
lines changed

src/db-backend/src/db.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use crate::expr_loader::ExprLoader;
1616
use crate::lang::Lang;
1717
use crate::replay::Replay;
1818
use crate::task::{
19-
Action, Breakpoint, Call, CallArg, CoreTrace, CtLoadLocalsArguments, Events, Location, ProgramEvent, RRTicks,
20-
VariableWithRecord, NO_INDEX, NO_PATH, NO_POSITION,
19+
Action, Breakpoint, Call, CallArg, CallLine, CoreTrace, CtLoadLocalsArguments, Events, Location, ProgramEvent,
20+
RRTicks, VariableWithRecord, NO_INDEX, NO_PATH, NO_POSITION,
2121
};
2222
use crate::value::{Type, Value, ValueRecordWithType};
2323

@@ -1215,6 +1215,11 @@ impl Replay for DbReplay {
12151215
self.db.load_step_events(step_id, exact)
12161216
}
12171217

1218+
fn load_callstack(&mut self) -> Result<Vec<CallLine>, Box<dyn Error>> {
1219+
warn!("load_callstack not implemented for db traces currently");
1220+
Ok(vec![])
1221+
}
1222+
12181223
fn jump_to(&mut self, step_id: StepId) -> Result<bool, Box<dyn Error>> {
12191224
self.step_id = step_id;
12201225
Ok(true)
@@ -1301,6 +1306,12 @@ impl Replay for DbReplay {
13011306
Ok(true)
13021307
}
13031308

1309+
fn callstack_jump(&mut self, _depth: usize) -> Result<(), Box<dyn Error>> {
1310+
// TODO? for now used only for rr
1311+
warn!("callstack_jump not implemented for db replay currently");
1312+
Ok(())
1313+
}
1314+
13041315
fn current_step_id(&mut self) -> StepId {
13051316
self.step_id
13061317
}

src/db-backend/src/handler.rs

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ use crate::task;
2828
use crate::task::{
2929
Action, Breakpoint, Call, CallArgsUpdateResults, CallLine, CallSearchArg, CalltraceLoadArgs,
3030
CalltraceNonExpandedKind, CollapseCallsArgs, CoreTrace, CtLoadFlowArguments, DbEventKind, FlowMode, FlowUpdate,
31-
FrameInfo, FunctionLocation, HistoryResult, HistoryUpdate, Instruction, Instructions, LoadHistoryArg,
32-
LoadStepLinesArg, LoadStepLinesUpdate, LocalStepJump, Location, MoveState, Notification, NotificationKind,
33-
ProgramEvent, RRGDBStopSignal, RRTicks, RegisterEventsArg, RunTracepointsArg, SourceCallJumpTarget, SourceLocation,
34-
StepArg, Stop, StopType, StringAndValueTuple, Task, TraceKind, TraceUpdate, TracepointId, TracepointResults,
35-
UpdateTableArgs, Variable, NO_INDEX, NO_PATH, NO_POSITION, NO_STEP_ID,
31+
FrameInfo, FunctionLocation, GlobalCallLineIndex, HistoryResult, HistoryUpdate, Instruction, Instructions,
32+
LoadHistoryArg, LoadStepLinesArg, LoadStepLinesUpdate, LocalStepJump, Location, MoveState, Notification,
33+
NotificationKind, ProgramEvent, RRGDBStopSignal, RRTicks, RegisterEventsArg, RunTracepointsArg,
34+
SourceCallJumpTarget, SourceLocation, StepArg, Stop, StopType, StringAndValueTuple, Task, TraceKind, TraceUpdate,
35+
TracepointId, TracepointResults, UpdateTableArgs, Variable, NO_INDEX, NO_PATH, NO_POSITION, NO_STEP_ID,
3636
};
3737
use crate::tracepoint_interpreter::TracepointInterpreter;
3838
use crate::value::{to_ct_value, Type, Value};
@@ -433,24 +433,39 @@ impl Handler {
433433
args: CalltraceLoadArgs,
434434
) -> Result<(), Box<dyn Error>> {
435435
if self.trace_kind == TraceKind::RR {
436-
warn!("load_calltrace_section not implemented for rr");
437-
return Ok(());
438-
}
439-
440-
let start_call_line_index = args.start_call_line_index;
441-
let call_lines = self.load_local_calltrace(args)?;
442-
let total_count = self.calc_total_calls();
443-
let position = self.calltrace.calc_scroll_position();
444-
let update = CallArgsUpdateResults::finished_update_call_lines(
445-
call_lines,
446-
start_call_line_index,
447-
total_count,
448-
position,
449-
self.calltrace.depth_offset,
450-
);
451-
// self.return_task((task, VOID_RESULT.to_string()))?;
452-
let raw_event = self.dap_client.updated_calltrace_event(&update)?;
453-
self.send_dap(&raw_event)?;
436+
// TODO: calltrace? eventually in the future
437+
// for now callstack!
438+
439+
let start_call_line_index = GlobalCallLineIndex(0);
440+
let callstack_lines = self.replay.load_callstack()?;
441+
let total_count = callstack_lines.len();
442+
let position = 0;
443+
let update = CallArgsUpdateResults::finished_update_call_lines(
444+
callstack_lines,
445+
start_call_line_index,
446+
total_count,
447+
position,
448+
self.calltrace.depth_offset,
449+
);
450+
let raw_event = self.dap_client.updated_calltrace_event(&update)?;
451+
self.send_dap(&raw_event)?;
452+
// warn!("load_calltrace_section not implemented for rr");
453+
} else {
454+
let start_call_line_index = args.start_call_line_index;
455+
let call_lines = self.load_local_calltrace(args)?;
456+
let total_count = self.calc_total_calls();
457+
let position = self.calltrace.calc_scroll_position();
458+
let update = CallArgsUpdateResults::finished_update_call_lines(
459+
call_lines,
460+
start_call_line_index,
461+
total_count,
462+
position,
463+
self.calltrace.depth_offset,
464+
);
465+
// self.return_task((task, VOID_RESULT.to_string()))?;
466+
let raw_event = self.dap_client.updated_calltrace_event(&update)?;
467+
self.send_dap(&raw_event)?;
468+
}
454469
Ok(())
455470
}
456471

@@ -662,10 +677,18 @@ impl Handler {
662677
}
663678

664679
pub fn calltrace_jump(&mut self, _req: dap::Request, location: Location) -> Result<(), Box<dyn Error>> {
665-
let step_id = StepId(location.rr_ticks.0); // using this field
666-
// for compat with rr/gdb core support
667-
self.replay.jump_to(step_id)?;
668-
self.step_id = self.replay.current_step_id();
680+
if self.trace_kind == TraceKind::DB {
681+
let step_id = StepId(location.rr_ticks.0); // using this field
682+
// for compat with rr/gdb core support
683+
self.replay.jump_to(step_id)?;
684+
self.step_id = self.replay.current_step_id();
685+
} else {
686+
// TODO: eventually calltrace in the future
687+
// for now support only callstack-mode
688+
self.replay.callstack_jump(location.callstack_depth)?;
689+
let _ = self.replay.load_location(&mut self.expr_loader)?;
690+
self.step_id = self.replay.current_step_id();
691+
}
669692
self.complete_move(false)?;
670693

671694
Ok(())

src/db-backend/src/query.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ pub enum CtRRQuery {
2020
DisableBreakpoints,
2121
JumpToCall { location: Location },
2222
LoadAllEvents,
23+
LoadCallstack,
2324
EventJump { program_event: ProgramEvent },
25+
CallstackJump { depth: usize },
2426
}

src/db-backend/src/replay.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use std::error::Error;
44
use crate::db::DbRecordEvent;
55
use crate::expr_loader::ExprLoader;
66
use crate::lang::Lang;
7-
use crate::task::{Action, Breakpoint, CtLoadLocalsArguments, Events, Location, ProgramEvent, VariableWithRecord};
7+
use crate::task::{
8+
Action, Breakpoint, CallLine, CtLoadLocalsArguments, Events, Location, ProgramEvent, VariableWithRecord,
9+
};
810
use crate::value::ValueRecordWithType;
911

1012
pub trait Replay: std::fmt::Debug {
@@ -20,6 +22,8 @@ pub trait Replay: std::fmt::Debug {
2022
fn load_return_value(&mut self, lang: Lang) -> Result<ValueRecordWithType, Box<dyn Error>>;
2123

2224
fn load_step_events(&mut self, step_id: StepId, exact: bool) -> Vec<DbRecordEvent>;
25+
fn load_callstack(&mut self) -> Result<Vec<CallLine>, Box<dyn Error>>;
26+
2327
fn jump_to(&mut self, step_id: StepId) -> Result<bool, Box<dyn Error>>;
2428
fn add_breakpoint(&mut self, path: &str, line: i64) -> Result<Breakpoint, Box<dyn Error>>;
2529
fn delete_breakpoint(&mut self, breakpoint: &Breakpoint) -> Result<bool, Box<dyn Error>>;
@@ -29,5 +33,7 @@ pub trait Replay: std::fmt::Debug {
2933
fn disable_breakpoints(&mut self) -> Result<(), Box<dyn Error>>;
3034
fn jump_to_call(&mut self, location: &Location) -> Result<Location, Box<dyn Error>>;
3135
fn event_jump(&mut self, event: &ProgramEvent) -> Result<bool, Box<dyn Error>>;
36+
fn callstack_jump(&mut self, depth: usize) -> Result<(), Box<dyn Error>>;
37+
3238
fn current_step_id(&mut self) -> StepId;
3339
}

src/db-backend/src/rr_dispatcher.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::process::{Child, Command, Stdio};
88
use std::thread;
99
use std::time::Duration;
1010

11-
use log::{error, info};
11+
use log::{error, info, warn};
1212
use runtime_tracing::StepId;
1313

1414
use crate::db::DbRecordEvent;
@@ -17,7 +17,9 @@ use crate::lang::Lang;
1717
use crate::paths::ct_rr_worker_socket_path;
1818
use crate::query::CtRRQuery;
1919
use crate::replay::Replay;
20-
use crate::task::{Action, Breakpoint, CtLoadLocalsArguments, Events, Location, ProgramEvent, VariableWithRecord};
20+
use crate::task::{
21+
Action, Breakpoint, CallLine, CtLoadLocalsArguments, Events, Location, ProgramEvent, VariableWithRecord,
22+
};
2123
use crate::value::ValueRecordWithType;
2224

2325
#[derive(Debug)]
@@ -243,9 +245,16 @@ impl Replay for RRDispatcher {
243245
fn load_step_events(&mut self, _step_id: StepId, _exact: bool) -> Vec<DbRecordEvent> {
244246
// TODO: maybe cache events directly in replay for now, and use the same logic for them as in Db?
245247
// or directly embed Db? or separate events in a separate EventList?
248+
warn!("load_step_events not implemented for rr traces");
246249
vec![]
247250
}
248251

252+
fn load_callstack(&mut self) -> Result<Vec<CallLine>, Box<dyn Error>> {
253+
self.ensure_active_stable()?;
254+
let res = serde_json::from_str::<Vec<CallLine>>(&self.stable.run_query(CtRRQuery::LoadCallstack)?)?;
255+
Ok(res)
256+
}
257+
249258
fn jump_to(&mut self, _step_id: StepId) -> Result<bool, Box<dyn Error>> {
250259
// TODO
251260
error!("TODO rr jump_to: for now run to entry");
@@ -318,6 +327,12 @@ impl Replay for RRDispatcher {
318327
)?)?)
319328
}
320329

330+
fn callstack_jump(&mut self, depth: usize) -> Result<(), Box<dyn Error>> {
331+
self.ensure_active_stable()?;
332+
self.stable.run_query(CtRRQuery::CallstackJump { depth })?;
333+
Ok(())
334+
}
335+
321336
fn current_step_id(&mut self) -> StepId {
322337
// cache location or step_id and return
323338
// OR always load from worker

src/frontend/types.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ type
733733
callValuePosition*: JsAssoc[cstring, float]
734734
width*: cstring
735735
resizeObserver*: ResizeObserver
736+
isCalltrace*: bool
736737

737738
debugger*: DebuggerService
738739
service*: CalltraceService

src/frontend/ui/calltrace.nim

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,15 @@ when defined(ctInExtension):
2828
result = calltraceComponentForExtension
2929

3030
proc calltraceJump(self: CalltraceComponent, location: types.Location) =
31+
# if not self.supportCallstackOnly:
3132
self.api.emit(CtCalltraceJump, location)
3233
self.api.emit(InternalNewOperation, NewOperation(stableBusy: true, name: "calltrace-jump"))
34+
# else:
35+
# self.callstackJump(location.depth)
36+
37+
# proc callstackJump(self: CalltraceComponent, depth: int) =
38+
# self.api.emit(CtCallstackJump, location)
39+
# self.api.emit(InternalNewOperation, NewOperation(stableBusy: true, name: "calltrace-jump"))
3340

3441
proc isAtStart(self: CalltraceComponent): bool =
3542
self.startCallLineIndex < START_BUFFER
@@ -848,8 +855,22 @@ method onUpdatedCalltrace*(self: CalltraceComponent, results: CtUpdatedCalltrace
848855

849856
self.redraw()
850857

858+
# proc processStackFrame*(self: CalltraceComponent, index: int, frame: DapStackFrame) =
859+
# # TODO
860+
# discard
861+
862+
# method onUpdatedStackTrace(self: CalltraceComponent, frames: seq[DapStackFrame]) =
863+
# self.callLines = @[]
864+
# self.args = JsAssoc[cstring, seq[CallKey]]()
865+
# self.returnValues = JsAssoc[cstring, Value]()
866+
# for i, frame in self.stackFrameToCallLine:
867+
# self.processStackFrame(i, frame)
868+
# self.redrawCallLines()
869+
# self.redraw()
870+
851871
func supportCallstackOnly(self: CalltraceComponent): bool =
852-
not self.config.calltrace or self.locationLang() == LangRust
872+
not self.config.calltrace or self.locationLang() == LangRust or not self.isDbBasedTrace
873+
853874

854875
method register*(self: CalltraceComponent, api: MediatorWithSubscribers) =
855876
self.api = api
@@ -868,7 +889,7 @@ proc registerCalltraceComponent*(component: CalltraceComponent, api: MediatorWit
868889
component.register(api)
869890

870891
proc loadLines(self: CalltraceComponent, fromScroll: bool) =
871-
if not (not self.isDbBasedTrace and fromScroll) or not self.loadedCallKeys.hasKey(self.lastSelectedCallKey):
892+
if not self.isDbBasedTrace or not (not self.isDbBasedTrace and fromScroll) or not self.loadedCallKeys.hasKey(self.lastSelectedCallKey):
872893
let depth = self.panelDepth()
873894
let height = self.panelHeight()
874895
let startBuffer = self.getStartBufferLen()

0 commit comments

Comments
 (0)