backtrace

This commit is contained in:
folkert van heusden 2024-04-16 20:52:26 +02:00
parent 9d4a552daf
commit e30cba36b1
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
3 changed files with 75 additions and 4 deletions

42
cpu.cpp
View file

@ -103,6 +103,27 @@ std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(c
return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time };
}
void cpu::add_to_stack_trace(const uint16_t p)
{
auto da = disassemble(p);
stacktrace.push_back({ p, da["instruction-text"][0] });
while (stacktrace.size() >= max_stacktrace_depth)
stacktrace.erase(stacktrace.begin());
}
void cpu::pop_from_stack_trace()
{
if (!stacktrace.empty())
stacktrace.pop_back();
}
std::vector<std::pair<uint16_t, std::string> > cpu::get_stack_trace() const
{
return stacktrace;
}
void cpu::reset()
{
memset(regs0_5, 0x00, sizeof regs0_5);
@ -1591,6 +1612,8 @@ bool cpu::misc_operations(const uint16_t instr)
return true;
case 0b0000000000000010: // RTI
if (debug_mode)
pop_from_stack_trace();
setPC(popStack());
setPSW(popStack(), !!getPSW_runmode());
psw &= ~020; // disable TRAP flag
@ -1605,6 +1628,8 @@ bool cpu::misc_operations(const uint16_t instr)
return true;
case 0b0000000000000110: // RTT
if (debug_mode)
pop_from_stack_trace();
setPC(popStack());
setPSW(popStack(), !!getPSW_runmode());
return true;
@ -1645,6 +1670,9 @@ bool cpu::misc_operations(const uint16_t instr)
}
if ((instr & 0b1111111000000000) == 0b0000100000000000) { // JSR
if (debug_mode)
add_to_stack_trace(instruction_start);
int dst_mode = (instr >> 3) & 7;
if (dst_mode == 0) // cannot jump to a register
return false;
@ -1674,6 +1702,9 @@ bool cpu::misc_operations(const uint16_t instr)
}
if ((instr & 0b1111111111111000) == 0b0000000010000000) { // RTS
if (debug_mode)
pop_from_stack_trace();
const int link_reg = instr & 7;
// MOVE link, PC
@ -1733,6 +1764,9 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt)
// TODO set MMR2?
}
if (debug_mode)
add_to_stack_trace(instruction_start);
// make sure the trap vector is retrieved from kernel space
psw &= 037777; // mask off 14/15 to make it into kernel-space
@ -2280,12 +2314,12 @@ void cpu::step()
instruction_count++;
try {
uint16_t temp_pc = getPC();
instruction_start = getPC();
if (!b->isMMR1Locked())
b->setMMR2(temp_pc);
b->setMMR2(instruction_start);
uint16_t instr = b->readWord(temp_pc);
uint16_t instr = b->readWord(instruction_start);
addRegister(7, rm_cur, 2);
@ -2301,7 +2335,7 @@ void cpu::step()
if (misc_operations(instr))
return;
DOLOG(warning, true, "UNHANDLED instruction %06o @ %06o", instr, temp_pc);
DOLOG(warning, true, "UNHANDLED instruction %06o @ %06o", instr, instruction_start);
trap(010); // floating point nog niet geimplementeerd
}

13
cpu.h
View file

@ -16,6 +16,8 @@
#include "bus.h"
constexpr const int max_stacktrace_depth = 16;
typedef struct {
int delta;
unsigned reg;
@ -42,6 +44,7 @@ private:
uint16_t regs0_5[2][6]; // R0...5, selected by bit 11 in PSW,
uint16_t sp[3 + 1]; // stackpointers, MF../MT.. select via 12/13 from PSW, others via 14/15
uint16_t pc { 0 };
uint16_t instruction_start { 0 };
uint16_t psw { 0 };
uint16_t fpsr { 0 };
uint16_t stackLimitRegister { 0377 };
@ -52,6 +55,9 @@ private:
bool it_is_a_trap { false };
uint64_t mtpi_count { 0 };
bool debug_mode { false };
std::vector<std::pair<uint16_t, std::string> > stacktrace;
// level, vector
std::map<uint8_t, std::set<uint8_t> > queued_interrupts;
#if defined(BUILD_FOR_RP2040)
@ -96,6 +102,9 @@ private:
operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const;
void add_to_stack_trace(const uint16_t p);
void pop_from_stack_trace();
public:
explicit cpu(bus *const b, std::atomic_uint32_t *const event);
~cpu();
@ -115,6 +124,10 @@ public:
uint64_t get_wait_time() const { return wait_time; }
std::tuple<double, double, uint64_t, uint32_t, double> get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_1s) const;
bool get_debug() const { return debug_mode; }
void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); }
std::vector<std::pair<uint16_t, std::string> > get_stack_trace() const;
void reset();
void step();

View file

@ -1005,10 +1005,32 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
else if (cmd == "turbo") {
turbo = !turbo;
if (turbo)
c->set_debug(false);
cnsl->put_string_lf(format("Turbo set to %s", turbo ? "ON" : "OFF"));
continue;
}
else if (cmd == "debug") {
bool new_mode = !c->get_debug();
c->set_debug(new_mode);
cnsl->put_string_lf(format("Debug mode set to %s", new_mode ? "ON" : "OFF"));
continue;
}
else if (cmd == "bt") {
if (c->get_debug() == false)
cnsl->put_string_lf("Debug mode is disabled!");
auto backtrace = c->get_stack_trace();
for(auto & element: backtrace)
cnsl->put_string_lf(format("%06o %s", element.first, element.second.c_str()));
continue;
}
else if (cmd == "quit" || cmd == "q") {
#if defined(ESP32)
ESP.restart();
@ -1030,6 +1052,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
cnsl->put_string_lf(" follows v/p (virtual/physical), all octal values, mmr0-3 are registers");
cnsl->put_string_lf("trace/t - toggle tracing");
cnsl->put_string_lf("turbo - toggle turbo mode (cannot be interrupted)");
cnsl->put_string_lf("debug - enable CPU debug mode");
cnsl->put_string_lf("bt - show backtrace - need to enable debug first");
cnsl->put_string_lf("strace - start tracing from address - invoke without address to disable");
cnsl->put_string_lf("trl - set trace run-level, empty for all");
cnsl->put_string_lf("regdump - dump register contents");