From 8cc6a305577ef5828349ae78e42ce0c6ea315f0a Mon Sep 17 00:00:00 2001 From: Eladash Date: Sun, 1 May 2022 15:04:56 +0300 Subject: [PATCH] Debugger: Fix instruction pointer for good --- rpcs3/rpcs3qt/debugger_frame.cpp | 24 ++++++++++++++++++++---- rpcs3/rpcs3qt/debugger_frame.h | 2 +- rpcs3/rpcs3qt/debugger_list.cpp | 31 +++++++++++++++++++++---------- rpcs3/rpcs3qt/debugger_list.h | 3 +++ 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index 600b6e781f..7550242dc5 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -160,7 +160,7 @@ debugger_frame::debugger_frame(std::shared_ptr 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, 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, 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) diff --git a/rpcs3/rpcs3qt/debugger_frame.h b/rpcs3/rpcs3qt/debugger_frame.h index fb2a8403ed..ddf0eee27b 100644 --- a/rpcs3/rpcs3qt/debugger_frame.h +++ b/rpcs3/rpcs3qt/debugger_frame.h @@ -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; }; diff --git a/rpcs3/rpcs3qt/debugger_list.cpp b/rpcs3/rpcs3qt/debugger_list.cpp index c17a320485..a9580101b7 100644 --- a/rpcs3/rpcs3qt/debugger_list.cpp +++ b/rpcs3/rpcs3qt/debugger_list.cpp @@ -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); } diff --git a/rpcs3/rpcs3qt/debugger_list.h b/rpcs3/rpcs3qt/debugger_list.h index 8fe7c24a12..0a53ed653b 100644 --- a/rpcs3/rpcs3qt/debugger_list.h +++ b/rpcs3/rpcs3qt/debugger_list.h @@ -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 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;