diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index 60bdd0b9f3..42d23dd06a 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -1250,6 +1250,29 @@ void debugger_frame::PerformGoToRequest(const QString& text_argument) } } +void debugger_frame::PerformGoToThreadRequest(const QString& text_argument) +{ + const u64 thread_id = EvaluateExpression(text_argument); + + if (thread_id != umax) + { + for (int i = 0; i < m_choice_units->count(); i++) + { + QVariant cpu = m_choice_units->itemData(i); + + if (cpu.canConvert()) + { + if (cpu_thread* ptr = cpu.value()(); ptr && ptr->id == thread_id) + { + // Success + m_choice_units->setCurrentIndex(i); + return; + } + } + } + } +} + void debugger_frame::PerformAddBreakpointRequest(u32 addr) { m_debugger_list->BreakpointRequested(addr, true); diff --git a/rpcs3/rpcs3qt/debugger_frame.h b/rpcs3/rpcs3qt/debugger_frame.h index d8af2f166a..05e9b450e0 100644 --- a/rpcs3/rpcs3qt/debugger_frame.h +++ b/rpcs3/rpcs3qt/debugger_frame.h @@ -95,6 +95,7 @@ public: void EnableButtons(bool enable); void ShowGotoAddressDialog(); void PerformGoToRequest(const QString& text_argument); + void PerformGoToThreadRequest(const QString& text_argument); void PerformAddBreakpointRequest(u32 addr); u64 EvaluateExpression(const QString& expression); void ClearBreakpoints() const; // Fallthrough method into breakpoint_list. diff --git a/rpcs3/rpcs3qt/log_frame.cpp b/rpcs3/rpcs3qt/log_frame.cpp index 663878efed..943b585f83 100644 --- a/rpcs3/rpcs3qt/log_frame.cpp +++ b/rpcs3/rpcs3qt/log_frame.cpp @@ -252,7 +252,14 @@ void log_frame::CreateAndConnectActions() connect(m_perform_goto_on_debugger, &QAction::triggered, [this]() { QPlainTextEdit* pte = (m_tabWidget->currentIndex() == 1 ? m_tty : m_log); - Q_EMIT PerformGoToOnDebugger(pte->textCursor().selectedText()); + Q_EMIT PerformGoToOnDebugger(pte->textCursor().selectedText(), true); + }); + + m_perform_goto_thread_on_debugger = new QAction(tr("Show Thread On The Debugger"), this); + connect(m_perform_goto_thread_on_debugger, &QAction::triggered, [this]() + { + QPlainTextEdit* pte = (m_tabWidget->currentIndex() == 1 ? m_tty : m_log); + Q_EMIT PerformGoToOnDebugger(pte->textCursor().selectedText(), false); }); m_stack_act_tty = new QAction(tr("Stack Mode (TTY)"), this); @@ -351,11 +358,14 @@ void log_frame::CreateAndConnectActions() QMenu* menu = m_log->createStandardContextMenu(); menu->addAction(m_clear_act); menu->addAction(m_perform_goto_on_debugger); + menu->addAction(m_perform_goto_thread_on_debugger); std::shared_ptr goto_signal_accepted = std::make_shared(false); - Q_EMIT PerformGoToOnDebugger("", true, goto_signal_accepted); + Q_EMIT PerformGoToOnDebugger("", true, true, goto_signal_accepted); m_perform_goto_on_debugger->setEnabled(m_log->textCursor().hasSelection() && *goto_signal_accepted); + m_perform_goto_thread_on_debugger->setEnabled(m_log->textCursor().hasSelection() && *goto_signal_accepted); m_perform_goto_on_debugger->setToolTip(tr("Jump to the selected hexadecimal address from the log text on the debugger.")); + m_perform_goto_thread_on_debugger->setToolTip(tr("Show the thread that corresponds to the thread ID from lthe log text on the debugger.")); menu->addSeparator(); menu->addActions(m_log_level_acts->actions()); @@ -373,7 +383,7 @@ void log_frame::CreateAndConnectActions() menu->addAction(m_perform_goto_on_debugger); std::shared_ptr goto_signal_accepted = std::make_shared(false); - Q_EMIT PerformGoToOnDebugger("", true, goto_signal_accepted); + Q_EMIT PerformGoToOnDebugger("", false, true, goto_signal_accepted); m_perform_goto_on_debugger->setEnabled(m_tty->textCursor().hasSelection() && *goto_signal_accepted); m_perform_goto_on_debugger->setToolTip(tr("Jump to the selected hexadecimal address from the TTY text on the debugger.")); diff --git a/rpcs3/rpcs3qt/log_frame.h b/rpcs3/rpcs3qt/log_frame.h index fc2b8c1b7b..f7e7484215 100644 --- a/rpcs3/rpcs3qt/log_frame.h +++ b/rpcs3/rpcs3qt/log_frame.h @@ -30,7 +30,7 @@ public Q_SLOTS: Q_SIGNALS: void LogFrameClosed(); - void PerformGoToOnDebugger(const QString& text_argument, bool test_only = false, std::shared_ptr signal_accepted = nullptr); + void PerformGoToOnDebugger(const QString& text_argument, bool is_address, bool test_only = false, std::shared_ptr signal_accepted = nullptr); protected: /** Override inherited method from Qt to allow signalling when close happened.*/ void closeEvent(QCloseEvent* event) override; @@ -73,6 +73,7 @@ private: QAction* m_clear_act = nullptr; QAction* m_clear_tty_act = nullptr; QAction* m_perform_goto_on_debugger = nullptr; + QAction* m_perform_goto_thread_on_debugger = nullptr; QActionGroup* m_log_level_acts = nullptr; QAction* m_nothing_act = nullptr; diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index ca6541e454..6e09815dfe 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -3071,7 +3071,7 @@ void main_window::CreateDockWindows() } }); - connect(m_log_frame, &log_frame::PerformGoToOnDebugger, this, [this](const QString& text_argument, bool test_only, std::shared_ptr signal_accepted) + connect(m_log_frame, &log_frame::PerformGoToOnDebugger, this, [this](const QString& text_argument, bool is_address, bool test_only, std::shared_ptr signal_accepted) { if (m_debugger_frame && m_debugger_frame->isVisible()) { @@ -3082,7 +3082,14 @@ void main_window::CreateDockWindows() if (!test_only) { - m_debugger_frame->PerformGoToRequest(text_argument); + if (is_address) + { + m_debugger_frame->PerformGoToRequest(text_argument); + } + else + { + m_debugger_frame->PerformGoToThreadRequest(text_argument); + } } } });