mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
Debugger: Fix instruction pointer for good
This commit is contained in:
parent
5c1f79ab26
commit
8cc6a30557
@ -160,7 +160,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
|
|||||||
setWidget(body);
|
setWidget(body);
|
||||||
|
|
||||||
connect(m_go_to_addr, &QAbstractButton::clicked, this, &debugger_frame::ShowGotoAddressDialog);
|
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, &QAbstractButton::clicked, this, &debugger_frame::DoStep);
|
||||||
connect(m_btn_step_over, &QAbstractButton::clicked, [this]() { DoStep(true); });
|
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);
|
cpu->state.notify_one(s_pause_flags);
|
||||||
|
m_debugger_list->EnableThreadFollowing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateUI();
|
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(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);
|
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();
|
UpdateUnitList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,6 +953,7 @@ void debugger_frame::OnSelectUnit()
|
|||||||
|
|
||||||
m_debugger_list->UpdateCPUData(get_cpu(), m_disasm.get());
|
m_debugger_list->UpdateCPUData(get_cpu(), m_disasm.get());
|
||||||
m_breakpoint_list->UpdateCPUData(get_cpu(), m_disasm.get());
|
m_breakpoint_list->UpdateCPUData(get_cpu(), m_disasm.get());
|
||||||
|
ShowPC(true);
|
||||||
DoUpdate();
|
DoUpdate();
|
||||||
UpdateUI();
|
UpdateUI();
|
||||||
}
|
}
|
||||||
@ -1077,13 +1079,18 @@ void debugger_frame::ClearCallStack()
|
|||||||
Q_EMIT CallStackUpdateRequested({});
|
Q_EMIT CallStackUpdateRequested({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugger_frame::ShowPC()
|
void debugger_frame::ShowPC(bool user_requested)
|
||||||
{
|
{
|
||||||
const auto cpu0 = get_cpu();
|
const auto cpu0 = get_cpu();
|
||||||
|
|
||||||
const u32 pc = (cpu0 ? cpu0->get_pc() : 0);
|
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)
|
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;
|
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 (const auto _state = +cpu->state; _state & s_pause_flags && _state & cpu_flag::wait && !(_state & cpu_flag::dbg_step))
|
||||||
{
|
{
|
||||||
if (should_step_over)
|
if (should_step_over)
|
||||||
|
@ -110,7 +110,7 @@ public Q_SLOTS:
|
|||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void OnSelectUnit();
|
void OnSelectUnit();
|
||||||
void ShowPC();
|
void ShowPC(bool user_requested = false);
|
||||||
void EnableUpdateTimer(bool enable) const;
|
void EnableUpdateTimer(bool enable) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
// 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
|
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
|
// The user wants to survey a specific memory location, do not interfere from this point forth
|
||||||
force = true;
|
m_follow_thread = false;
|
||||||
center_pc = 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)
|
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->setForeground(m_text_color_pc);
|
||||||
list_item->setBackground(m_color_pc);
|
list_item->setBackground(m_color_pc);
|
||||||
}
|
}
|
||||||
|
else if (select_addr && pc == addr)
|
||||||
|
{
|
||||||
|
list_item->setSelected(true);
|
||||||
|
}
|
||||||
else if (IsBreakpoint(pc))
|
else if (IsBreakpoint(pc))
|
||||||
{
|
{
|
||||||
list_item->setForeground(m_text_color_bp);
|
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);
|
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))
|
if (m_cpu->id_type() == 1 && !vm::check_addr(pc, 0))
|
||||||
{
|
{
|
||||||
list_item->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(fmt::format("[%08x] ?? ?? ?? ??:", pc)));
|
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);
|
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)
|
void debugger_list::scroll(s32 steps)
|
||||||
{
|
{
|
||||||
while (m_cpu && m_cpu->id_type() == 0x55 && steps > 0)
|
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);
|
ShowAddress(m_pc + (steps * 4), false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ class debugger_list : public QListWidget
|
|||||||
public:
|
public:
|
||||||
u32 m_pc = 0;
|
u32 m_pc = 0;
|
||||||
u32 m_item_count = 30;
|
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_bp;
|
||||||
QColor m_color_pc;
|
QColor m_color_pc;
|
||||||
QColor m_text_color_bp;
|
QColor m_text_color_bp;
|
||||||
@ -29,8 +30,10 @@ Q_SIGNALS:
|
|||||||
public:
|
public:
|
||||||
debugger_list(QWidget* parent, std::shared_ptr<gui_settings> settings, breakpoint_handler* handler);
|
debugger_list(QWidget* parent, std::shared_ptr<gui_settings> settings, breakpoint_handler* handler);
|
||||||
void UpdateCPUData(cpu_thread* cpu, CPUDisAsm* disasm);
|
void UpdateCPUData(cpu_thread* cpu, CPUDisAsm* disasm);
|
||||||
|
void EnableThreadFollowing(bool enable = true);
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void ShowAddress(u32 addr, bool select_addr = true, bool force = false);
|
void ShowAddress(u32 addr, bool select_addr = true, bool force = false);
|
||||||
|
void RefreshView();
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
void mouseDoubleClickEvent(QMouseEvent* event) override;
|
void mouseDoubleClickEvent(QMouseEvent* event) override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user