Add instruction tracing to step_fast and improve error messages
step_fast() never recorded trace entries, so crash dumps always showed an empty trace. Now records PC + opcode info in the same deque as step(). Also includes exception type in player-facing error messages when the exception string is empty.
This commit is contained in:
parent
c8d9bdfae9
commit
5a98adb6ee
2 changed files with 14 additions and 3 deletions
|
|
@ -165,7 +165,8 @@ class EmbeddedIFSession:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
tb = traceback.format_exc()
|
tb = traceback.format_exc()
|
||||||
logger.error(f"Interpreter crashed:\n{tb}")
|
logger.error(f"Interpreter crashed:\n{tb}")
|
||||||
self._error = f"interpreter error: {e}"
|
msg = str(e) or type(e).__name__
|
||||||
|
self._error = f"interpreter error: {msg}"
|
||||||
finally:
|
finally:
|
||||||
self._done = True
|
self._done = True
|
||||||
self._keyboard._waiting.set()
|
self._keyboard._waiting.set()
|
||||||
|
|
|
||||||
|
|
@ -226,17 +226,27 @@ class ZCpu:
|
||||||
return table
|
return table
|
||||||
|
|
||||||
def step_fast(self):
|
def step_fast(self):
|
||||||
"""Execute a single instruction without tracing.
|
"""Execute a single instruction with lightweight tracing.
|
||||||
|
|
||||||
Returns True if execution should continue.
|
Returns True if execution should continue.
|
||||||
"""
|
"""
|
||||||
|
current_pc = self._opdecoder.program_counter
|
||||||
(opcode_class, opcode_number, operands) = self._opdecoder.get_next_instruction()
|
(opcode_class, opcode_number, operands) = self._opdecoder.get_next_instruction()
|
||||||
entry = self._dispatch[opcode_class][opcode_number]
|
entry = self._dispatch[opcode_class][opcode_number]
|
||||||
if entry is None:
|
if entry is None:
|
||||||
raise ZCpuIllegalInstruction
|
self._trace.append(f" {current_pc:06x} ILLEGAL")
|
||||||
|
self._dump_trace()
|
||||||
|
raise ZCpuIllegalInstruction(
|
||||||
|
f"illegal opcode class={opcode_class} num={opcode_number}"
|
||||||
|
f" at PC={current_pc:#x}"
|
||||||
|
)
|
||||||
implemented, func = entry
|
implemented, func = entry
|
||||||
if not implemented:
|
if not implemented:
|
||||||
return False
|
return False
|
||||||
|
self._trace.append(
|
||||||
|
f" {current_pc:06x} {func.__name__}"
|
||||||
|
f"({', '.join(str(x) for x in operands)})"
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
func(self, *operands)
|
func(self, *operands)
|
||||||
except (ZCpuQuit, ZCpuRestart):
|
except (ZCpuQuit, ZCpuRestart):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue