1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 12:12:50 +01:00

Debugger: Fix instruction pointer for good

This commit is contained in:
Eladash 2022-05-01 15:04:56 +03:00 committed by Ivan
parent 5c1f79ab26
commit 8cc6a30557
4 changed files with 45 additions and 15 deletions

View File

@ -160,7 +160,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
setWidget(body);
connect(m_go_to_addr, &QAbstractButton::clicked, this, &debugger_frame::ShowGotoAddressDialog);
connect(m_go_to_pc, &QAbstractButton::clicked, this, &debugger_frame::ShowPC);
connect(m_go_to_pc, &QAbstractButton::clicked, this, [this]() { ShowPC(true); });
connect(m_btn_step, &QAbstractButton::clicked, this, &debugger_frame::DoStep);
connect(m_btn_step_over, &QAbstractButton::clicked, [this]() { DoStep(true); });
@ -193,6 +193,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
}
cpu->state.notify_one(s_pause_flags);
m_debugger_list->EnableThreadFollowing();
}
}
UpdateUI();
@ -213,7 +214,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
connect(this, &debugger_frame::CallStackUpdateRequested, m_call_stack_list, &call_stack_list::HandleUpdate);
connect(m_call_stack_list, &call_stack_list::RequestShowAddress, m_debugger_list, &debugger_list::ShowAddress);
m_debugger_list->ShowAddress(m_debugger_list->m_pc, false);
m_debugger_list->RefreshView();
UpdateUnitList();
}
@ -952,6 +953,7 @@ void debugger_frame::OnSelectUnit()
m_debugger_list->UpdateCPUData(get_cpu(), m_disasm.get());
m_breakpoint_list->UpdateCPUData(get_cpu(), m_disasm.get());
ShowPC(true);
DoUpdate();
UpdateUI();
}
@ -1077,13 +1079,18 @@ void debugger_frame::ClearCallStack()
Q_EMIT CallStackUpdateRequested({});
}
void debugger_frame::ShowPC()
void debugger_frame::ShowPC(bool user_requested)
{
const auto cpu0 = get_cpu();
const u32 pc = (cpu0 ? cpu0->get_pc() : 0);
m_debugger_list->ShowAddress(pc, true);
if (user_requested)
{
m_debugger_list->EnableThreadFollowing();
}
m_debugger_list->ShowAddress(pc, false);
}
void debugger_frame::DoStep(bool step_over)
@ -1092,6 +1099,15 @@ void debugger_frame::DoStep(bool step_over)
{
bool should_step_over = step_over && cpu->id_type() == 1;
// If stepping over, lay at the same spot and wait for the thread to finish the call
// If not, fixate on the current pointed instruction
m_debugger_list->EnableThreadFollowing(!should_step_over);
if (should_step_over)
{
m_debugger_list->ShowAddress(cpu->get_pc() + 4, false);
}
if (const auto _state = +cpu->state; _state & s_pause_flags && _state & cpu_flag::wait && !(_state & cpu_flag::dbg_step))
{
if (should_step_over)

View File

@ -110,7 +110,7 @@ public Q_SLOTS:
private Q_SLOTS:
void OnSelectUnit();
void ShowPC();
void ShowPC(bool user_requested = false);
void EnableUpdateTimer(bool enable) const;
};

View File

@ -56,14 +56,13 @@ void debugger_list::ShowAddress(u32 addr, bool select_addr, bool force)
// How many spaces addr can move down without us needing to move the entire view
const u32 addr_margin = (m_item_count / (center_pc ? 2 : 1) - 4); // 4 is just a buffer of 4 spaces at the bottom
if (m_cpu && m_cpu->id_type() == 0x55)
if (select_addr || force)
{
// RSX instructions' size is not consistent, this is the only valid mode for it
force = true;
center_pc = false;
// The user wants to survey a specific memory location, do not interfere from this point forth
m_follow_thread = false;
}
if (force || addr - m_pc > addr_margin * 4) // 4 is the number of bytes in each instruction
if (force || ((m_follow_thread || select_addr) && addr - m_pc > addr_margin * 4)) // 4 is the number of bytes in each instruction
{
if (center_pc)
{
@ -104,6 +103,10 @@ void debugger_list::ShowAddress(u32 addr, bool select_addr, bool force)
list_item->setForeground(m_text_color_pc);
list_item->setBackground(m_color_pc);
}
else if (select_addr && pc == addr)
{
list_item->setSelected(true);
}
else if (IsBreakpoint(pc))
{
list_item->setForeground(m_text_color_bp);
@ -115,11 +118,6 @@ void debugger_list::ShowAddress(u32 addr, bool select_addr, bool force)
list_item->setBackground(default_background);
}
if (select_addr && pc == addr)
{
list_item->setSelected(true);
}
if (m_cpu->id_type() == 1 && !vm::check_addr(pc, 0))
{
list_item->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(fmt::format("[%08x] ?? ?? ?? ??:", pc)));
@ -155,6 +153,18 @@ void debugger_list::ShowAddress(u32 addr, bool select_addr, bool force)
setLineWidth(-1);
}
void debugger_list::RefreshView()
{
const bool old = std::exchange(m_follow_thread, false);
ShowAddress(0, false);
m_follow_thread = old;
}
void debugger_list::EnableThreadFollowing(bool enable)
{
m_follow_thread = enable;
}
void debugger_list::scroll(s32 steps)
{
while (m_cpu && m_cpu->id_type() == 0x55 && steps > 0)
@ -175,6 +185,7 @@ void debugger_list::scroll(s32 steps)
}
}
EnableThreadFollowing(false);
ShowAddress(m_pc + (steps * 4), false, true);
}

View File

@ -19,6 +19,7 @@ class debugger_list : public QListWidget
public:
u32 m_pc = 0;
u32 m_item_count = 30;
bool m_follow_thread = true; // If true, follow the selected thread to wherever it goes in code
QColor m_color_bp;
QColor m_color_pc;
QColor m_text_color_bp;
@ -29,8 +30,10 @@ Q_SIGNALS:
public:
debugger_list(QWidget* parent, std::shared_ptr<gui_settings> settings, breakpoint_handler* handler);
void UpdateCPUData(cpu_thread* cpu, CPUDisAsm* disasm);
void EnableThreadFollowing(bool enable = true);
public Q_SLOTS:
void ShowAddress(u32 addr, bool select_addr = true, bool force = false);
void RefreshView();
protected:
void keyPressEvent(QKeyEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event) override;