added stepping functionality to the debugger

float_support
Anton Lydike 4 years ago
parent 521cb73ad6
commit 39d5212d3d

@ -25,6 +25,7 @@ class CPU:
self.exit = False
self.exit_code = 0
self.conf = conf
self.active_debug = False # if a debugging session is currently runnign
# setup MMU, registers and syscall handlers
self.mmu = MMU(conf)
@ -66,7 +67,30 @@ class CPU:
self.__run()
def __run(self):
def continue_from_debugger(self, verbose=True):
"""
dalled from the debugger to continue running
"""
self.__run(verbose)
def step(self):
if self.exit:
print(FMT_CPU + "Program exited with code {}".format(self.exit_code) + FMT_NONE)
else:
try:
self.cycle += 1
ins = self.mmu.read_ins(self.pc)
print("Running instruction {} from 0x{:08X}".format(ins, self.pc))
self.pc += 1
self.__run_instruction(ins)
except LaunchDebuggerException:
print(FMT_CPU + "[CPU] Returning to debugger!" + FMT_NONE)
except RiscemuBaseException as ex:
self.pc -= 1
print(ex.message())
def __run(self, verbose=False):
if self.pc <= 0:
return False
ins = None
@ -74,14 +98,22 @@ class CPU:
while not self.exit:
self.cycle += 1
ins = self.mmu.read_ins(self.pc)
if verbose:
print(FMT_CPU + " Running 0x{:08X}:{} {}".format(self.pc, FMT_NONE, ins))
self.pc += 1
self.__run_instruction(ins)
except RiscemuBaseException as ex:
print(FMT_ERROR + "[CPU] excpetion caught at 0x{:08X}: {}:".format(self.pc-1, ins) + FMT_NONE)
print(" " + ex.message())
if not isinstance(ex, LaunchDebuggerException):
print(FMT_ERROR + "[CPU] excpetion caught at 0x{:08X}: {}:".format(self.pc-1, ins) + FMT_NONE)
print(ex.message())
self.pc -= 1
if self.active_debug:
print(FMT_CPU + "[CPU] Returning to debugger!" + FMT_NONE)
return
if self.conf.debug_on_exception:
launch_debug_session(self, self.mmu, self.regs,
"Exception encountered, launching debug:".format(self.pc-1))
"Exception encountered, launching debug:")
print()
print(FMT_CPU + "Program exited with code {}".format(self.exit_code) + FMT_NONE)

@ -134,3 +134,9 @@ class NumberFormatException(RiscemuBaseException):
self.__class__.__name__,
self.msg
)
# this exception is not printed and simply signals that an interactive debugging session is
class LaunchDebuggerException(RiscemuBaseException):
def message(self):
return ""

@ -1,31 +1,46 @@
import typing
from .Registers import Registers
if typing.TYPE_CHECKING:
from . import *
def launch_debug_session(cpu: 'CPU', mmu: 'MMU', reg: 'Registers', prompt=""):
if not cpu.conf.debug_instruction:
if not cpu.conf.debug_instruction or cpu.active_debug:
return
import code
import readline
import rlcompleter
# setup some aliases
cpu.active_debug = True
# setup some aliases:
registers = reg
regs = reg
memory = mmu
mem = mmu
syscall_interface = cpu.syscall_int
# setup helper functions:
def dump(what, *args, **kwargs):
if isinstance(what, Registers):
regs.dump(*args, **kwargs)
else:
mmu.dump(what, *args, **kwargs)
def ins():
print("Current instruction at 0x{:08X}:".format(cpu.pc))
return mmu.read_ins(cpu.pc)
def cont(verbose=True):
cpu.continue_from_debugger(verbose)
def step():
cpu.step()
sess_vars = globals()
sess_vars.update(locals())
readline.set_completer(rlcompleter.Completer(sess_vars).complete)
readline.parse_and_bind("tab: complete")
code.InteractiveConsole(sess_vars).interact(banner=prompt, exitmsg="Resuming simulation")
code.InteractiveConsole(sess_vars).interact(banner=prompt, exitmsg="Exiting debugger")
cpu.active_debug = False

@ -271,7 +271,10 @@ class RV32I(InstructionSet):
def instruction_sbreak(self, ins: 'LoadedInstruction'):
ASSERT_LEN(ins.args, 0)
launch_debug_session(self.cpu, self.mmu, self.regs, "Debug instruction encountered at 0x{:08X}".format(self.pc))
if self.cpu.active_debug:
print("Debug instruction encountered at 0x{:08X}".format(self.pc-1))
raise LaunchDebuggerException()
launch_debug_session(self.cpu, self.mmu, self.regs, "Debug instruction encountered at 0x{:08X}".format(self.pc-1))
def instruction_nop(self, ins: 'LoadedInstruction'):
ASSERT_LEN(ins.args, 0)

Loading…
Cancel
Save