mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 14:01:25 +12:00
Logs/Debugger: Go-To-Address signal from log text
This commit is contained in:
parent
e83540d80c
commit
c70338a9a9
5 changed files with 83 additions and 16 deletions
|
@ -859,6 +859,7 @@ void debugger_frame::UpdateUnitList()
|
||||||
{
|
{
|
||||||
if (m_reg_editor) m_reg_editor->close();
|
if (m_reg_editor) m_reg_editor->close();
|
||||||
if (m_inst_editor) m_inst_editor->close();
|
if (m_inst_editor) m_inst_editor->close();
|
||||||
|
if (m_goto_dialog) m_goto_dialog->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emu_state == system_state::stopped)
|
if (emu_state == system_state::stopped)
|
||||||
|
@ -1008,9 +1009,16 @@ void debugger_frame::WritePanels()
|
||||||
|
|
||||||
void debugger_frame::ShowGotoAddressDialog()
|
void debugger_frame::ShowGotoAddressDialog()
|
||||||
{
|
{
|
||||||
QDialog* dlg = new QDialog(this);
|
if (m_goto_dialog)
|
||||||
dlg->setWindowTitle(tr("Go To Address"));
|
{
|
||||||
dlg->setModal(true);
|
m_goto_dialog->move(QCursor::pos());
|
||||||
|
m_goto_dialog->show();
|
||||||
|
m_goto_dialog->setFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_goto_dialog = new QDialog(this);
|
||||||
|
m_goto_dialog->setWindowTitle(tr("Go To Address"));
|
||||||
|
|
||||||
// Panels
|
// Panels
|
||||||
QVBoxLayout* vbox_panel(new QVBoxLayout());
|
QVBoxLayout* vbox_panel(new QVBoxLayout());
|
||||||
|
@ -1018,7 +1026,7 @@ void debugger_frame::ShowGotoAddressDialog()
|
||||||
QHBoxLayout* hbox_button_panel(new QHBoxLayout());
|
QHBoxLayout* hbox_button_panel(new QHBoxLayout());
|
||||||
|
|
||||||
// Address expression input
|
// Address expression input
|
||||||
QLineEdit* expression_input(new QLineEdit(dlg));
|
QLineEdit* expression_input(new QLineEdit(m_goto_dialog));
|
||||||
expression_input->setFont(m_mono);
|
expression_input->setFont(m_mono);
|
||||||
expression_input->setMaxLength(18);
|
expression_input->setMaxLength(18);
|
||||||
|
|
||||||
|
@ -1044,9 +1052,10 @@ void debugger_frame::ShowGotoAddressDialog()
|
||||||
vbox_panel->addSpacing(8);
|
vbox_panel->addSpacing(8);
|
||||||
vbox_panel->addLayout(hbox_button_panel);
|
vbox_panel->addLayout(hbox_button_panel);
|
||||||
|
|
||||||
dlg->setLayout(vbox_panel);
|
m_goto_dialog->setLayout(vbox_panel);
|
||||||
|
|
||||||
const auto cpu = get_cpu();
|
const auto cpu_check = make_check_cpu(get_cpu());
|
||||||
|
const auto cpu = cpu_check();
|
||||||
const QFont font = expression_input->font();
|
const QFont font = expression_input->font();
|
||||||
|
|
||||||
// -1 from get_pc() turns into 0
|
// -1 from get_pc() turns into 0
|
||||||
|
@ -1054,18 +1063,35 @@ void debugger_frame::ShowGotoAddressDialog()
|
||||||
expression_input->setPlaceholderText(QString("0x%1").arg(pc, 16, 16, QChar('0')));
|
expression_input->setPlaceholderText(QString("0x%1").arg(pc, 16, 16, QChar('0')));
|
||||||
expression_input->setFixedWidth(gui::utils::get_label_width(expression_input->placeholderText(), &font));
|
expression_input->setFixedWidth(gui::utils::get_label_width(expression_input->placeholderText(), &font));
|
||||||
|
|
||||||
connect(button_ok, &QAbstractButton::clicked, dlg, &QDialog::accept);
|
connect(button_ok, &QAbstractButton::clicked, m_goto_dialog, &QDialog::accept);
|
||||||
connect(button_cancel, &QAbstractButton::clicked, dlg, &QDialog::reject);
|
connect(button_cancel, &QAbstractButton::clicked, m_goto_dialog, &QDialog::reject);
|
||||||
|
|
||||||
dlg->move(QCursor::pos());
|
m_goto_dialog->move(QCursor::pos());
|
||||||
|
m_goto_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
if (dlg->exec() == QDialog::Accepted)
|
connect(m_goto_dialog, &QDialog::finished, this, [this, cpu, cpu_check, expression_input](int result)
|
||||||
{
|
{
|
||||||
const u32 address = EvaluateExpression(expression_input->text());
|
// Check if the thread has not been destroyed and is still the focused since
|
||||||
m_debugger_list->ShowAddress(address, true);
|
// This also works if no thread is selected and has been selected before
|
||||||
}
|
if (result == QDialog::Accepted && cpu == get_cpu() && cpu == cpu_check())
|
||||||
|
{
|
||||||
|
PerformGoToRequest(expression_input->text());
|
||||||
|
}
|
||||||
|
|
||||||
dlg->deleteLater();
|
m_goto_dialog = nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_goto_dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugger_frame::PerformGoToRequest(const QString& text_argument)
|
||||||
|
{
|
||||||
|
const u64 address = EvaluateExpression(text_argument);
|
||||||
|
|
||||||
|
if (address != umax)
|
||||||
|
{
|
||||||
|
m_debugger_list->ShowAddress(static_cast<u32>(address), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 debugger_frame::EvaluateExpression(const QString& expression)
|
u64 debugger_frame::EvaluateExpression(const QString& expression)
|
||||||
|
@ -1077,8 +1103,8 @@ u64 debugger_frame::EvaluateExpression(const QString& expression)
|
||||||
const u64 res = static_cast<u64>(fixed_expression.toULong(&ok, 16));
|
const u64 res = static_cast<u64>(fixed_expression.toULong(&ok, 16));
|
||||||
|
|
||||||
if (ok) return res;
|
if (ok) return res;
|
||||||
if (const auto thread = get_cpu()) return thread->get_pc();
|
if (const auto thread = get_cpu(); thread && expression.isEmpty()) return thread->get_pc();
|
||||||
return 0;
|
return umax;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugger_frame::ClearBreakpoints() const
|
void debugger_frame::ClearBreakpoints() const
|
||||||
|
|
|
@ -71,6 +71,7 @@ class debugger_frame : public custom_dock_widget
|
||||||
call_stack_list* m_call_stack_list;
|
call_stack_list* m_call_stack_list;
|
||||||
instruction_editor_dialog* m_inst_editor = nullptr;
|
instruction_editor_dialog* m_inst_editor = nullptr;
|
||||||
register_editor_dialog* m_reg_editor = nullptr;
|
register_editor_dialog* m_reg_editor = nullptr;
|
||||||
|
QDialog* m_goto_dialog = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<gui_settings> m_gui_settings;
|
std::shared_ptr<gui_settings> m_gui_settings;
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ public:
|
||||||
void WritePanels();
|
void WritePanels();
|
||||||
void EnableButtons(bool enable);
|
void EnableButtons(bool enable);
|
||||||
void ShowGotoAddressDialog();
|
void ShowGotoAddressDialog();
|
||||||
|
void PerformGoToRequest(const QString& text_argument);
|
||||||
u64 EvaluateExpression(const QString& expression);
|
u64 EvaluateExpression(const QString& expression);
|
||||||
void ClearBreakpoints() const; // Fallthrough method into breakpoint_list.
|
void ClearBreakpoints() const; // Fallthrough method into breakpoint_list.
|
||||||
void ClearCallStack();
|
void ClearCallStack();
|
||||||
|
|
|
@ -241,6 +241,13 @@ void log_frame::CreateAndConnectActions()
|
||||||
m_tty->clear();
|
m_tty->clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_perform_goto_on_debugger = new QAction(tr("Go-To On The Debugger"), this);
|
||||||
|
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());
|
||||||
|
});
|
||||||
|
|
||||||
m_stack_act_tty = new QAction(tr("Stack Mode (TTY)"), this);
|
m_stack_act_tty = new QAction(tr("Stack Mode (TTY)"), this);
|
||||||
m_stack_act_tty->setCheckable(true);
|
m_stack_act_tty->setCheckable(true);
|
||||||
connect(m_stack_act_tty, &QAction::toggled, [this](bool checked)
|
connect(m_stack_act_tty, &QAction::toggled, [this](bool checked)
|
||||||
|
@ -336,6 +343,13 @@ void log_frame::CreateAndConnectActions()
|
||||||
{
|
{
|
||||||
QMenu* menu = m_log->createStandardContextMenu();
|
QMenu* menu = m_log->createStandardContextMenu();
|
||||||
menu->addAction(m_clear_act);
|
menu->addAction(m_clear_act);
|
||||||
|
menu->addAction(m_perform_goto_on_debugger);
|
||||||
|
|
||||||
|
std::shared_ptr<bool> goto_signal_accepted = std::make_shared<bool>(false);
|
||||||
|
Q_EMIT PerformGoToOnDebugger("", true, goto_signal_accepted);
|
||||||
|
m_perform_goto_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."));
|
||||||
|
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addActions(m_log_level_acts->actions());
|
menu->addActions(m_log_level_acts->actions());
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
@ -349,6 +363,13 @@ void log_frame::CreateAndConnectActions()
|
||||||
{
|
{
|
||||||
QMenu* menu = m_tty->createStandardContextMenu();
|
QMenu* menu = m_tty->createStandardContextMenu();
|
||||||
menu->addAction(m_clear_tty_act);
|
menu->addAction(m_clear_tty_act);
|
||||||
|
menu->addAction(m_perform_goto_on_debugger);
|
||||||
|
|
||||||
|
std::shared_ptr<bool> goto_signal_accepted = std::make_shared<bool>(false);
|
||||||
|
Q_EMIT PerformGoToOnDebugger("", 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."));
|
||||||
|
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addAction(m_tty_act);
|
menu->addAction(m_tty_act);
|
||||||
menu->addAction(m_stack_act_tty);
|
menu->addAction(m_stack_act_tty);
|
||||||
|
|
|
@ -30,6 +30,7 @@ public Q_SLOTS:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void LogFrameClosed();
|
void LogFrameClosed();
|
||||||
|
void PerformGoToOnDebugger(const QString& text_argument, bool test_only = false, std::shared_ptr<bool> signal_accepted = nullptr);
|
||||||
protected:
|
protected:
|
||||||
/** Override inherited method from Qt to allow signalling when close happened.*/
|
/** Override inherited method from Qt to allow signalling when close happened.*/
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
@ -71,6 +72,7 @@ private:
|
||||||
|
|
||||||
QAction* m_clear_act = nullptr;
|
QAction* m_clear_act = nullptr;
|
||||||
QAction* m_clear_tty_act = nullptr;
|
QAction* m_clear_tty_act = nullptr;
|
||||||
|
QAction* m_perform_goto_on_debugger = nullptr;
|
||||||
|
|
||||||
QActionGroup* m_log_level_acts = nullptr;
|
QActionGroup* m_log_level_acts = nullptr;
|
||||||
QAction* m_nothing_act = nullptr;
|
QAction* m_nothing_act = nullptr;
|
||||||
|
|
|
@ -2793,6 +2793,22 @@ void main_window::CreateDockWindows()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(m_log_frame, &log_frame::PerformGoToOnDebugger, this, [this](const QString& text_argument, bool test_only, std::shared_ptr<bool> signal_accepted)
|
||||||
|
{
|
||||||
|
if (m_debugger_frame && m_debugger_frame->isVisible())
|
||||||
|
{
|
||||||
|
if (signal_accepted)
|
||||||
|
{
|
||||||
|
*signal_accepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test_only)
|
||||||
|
{
|
||||||
|
m_debugger_frame->PerformGoToRequest(text_argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
connect(m_debugger_frame, &debugger_frame::DebugFrameClosed, this, [this]()
|
connect(m_debugger_frame, &debugger_frame::DebugFrameClosed, this, [this]()
|
||||||
{
|
{
|
||||||
if (ui->showDebuggerAct->isChecked())
|
if (ui->showDebuggerAct->isChecked())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue