@@ -7,6 +7,7 @@ use gdbstub::stub::{BaseStopReason, SingleThreadStopReason};
77use gdbstub:: target:: ext:: base:: singlethread:: {
88 SingleThreadBase ,
99 SingleThreadResume , SingleThreadResumeOps ,
10+ SingleThreadSingleStep , SingleThreadSingleStepOps ,
1011} ;
1112use gdbstub:: target:: ext:: base:: BaseOps ;
1213use gdbstub:: target:: ext:: breakpoints:: {
@@ -101,6 +102,8 @@ pub struct HyperlightKvmSandboxTarget {
101102
102103 /// vCPU paused state
103104 paused : bool ,
105+ /// vCPU stepping state
106+ single_step : bool ,
104107
105108 /// Array of addresses for HW breakpoints
106109 hw_breakpoints : Vec < u64 > ,
@@ -125,6 +128,7 @@ impl HyperlightKvmSandboxTarget {
125128 entrypoint,
126129
127130 paused : false ,
131+ single_step : false ,
128132
129133 hw_breakpoints : vec ! [ ] ,
130134
@@ -146,6 +150,13 @@ impl HyperlightKvmSandboxTarget {
146150
147151 /// Get the reason the vCPU has stopped
148152 pub fn get_stop_reason ( & self ) -> Result < Option < BaseStopReason < ( ) , u64 > > , GdbTargetError > {
153+ if self . single_step {
154+ return Ok ( Some ( SingleThreadStopReason :: SignalWithThread {
155+ tid : ( ) ,
156+ signal : Signal :: SIGTRAP ,
157+ } ) ) ;
158+ }
159+
149160 let ip = self . get_instruction_pointer ( ) ?;
150161
151162 if self . hw_breakpoints . contains ( & ip) {
@@ -159,6 +170,15 @@ impl HyperlightKvmSandboxTarget {
159170 Ok ( None )
160171 }
161172
173+ fn set_single_step ( & mut self , enable : bool ) -> Result < ( ) , GdbTargetError > {
174+ self . single_step = enable;
175+
176+ self . debug
177+ . set_breakpoints ( & self . vcpu_fd . lock ( ) . unwrap ( ) , & self . hw_breakpoints , enable) ?;
178+
179+ Ok ( ( ) )
180+ }
181+
162182 /// This method provides a way to set a breakpoint at the entrypoint
163183 /// it does not keep this breakpoint set after the vcpu already stopped at the address
164184 pub fn set_entrypoint_bp ( & mut self ) -> Result < bool , GdbTargetError > {
@@ -472,6 +492,20 @@ impl HwBreakpoint for HyperlightKvmSandboxTarget {
472492impl SingleThreadResume for HyperlightKvmSandboxTarget {
473493 fn resume ( & mut self , _signal : Option < Signal > ) -> Result < ( ) , Self :: Error > {
474494 log:: debug!( "Resume" ) ;
495+ self . set_single_step ( false ) ?;
496+ self . resume_vcpu ( )
497+ }
498+ fn support_single_step ( & mut self ) -> Option < SingleThreadSingleStepOps < Self > > {
499+ Some ( self )
500+ }
501+ }
502+
503+ impl SingleThreadSingleStep for HyperlightKvmSandboxTarget {
504+ fn step ( & mut self , signal : Option < Signal > ) -> Result < ( ) , Self :: Error > {
505+ assert ! ( signal. is_none( ) ) ;
506+
507+ log:: debug!( "Step" ) ;
508+ self . set_single_step ( true ) ?;
475509 self . resume_vcpu ( )
476510 }
477511}
0 commit comments