|
|
|
@@ -166,42 +166,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
|
|
|
|
|
connect(m_btn_step, &QAbstractButton::clicked, this, &debugger_frame::DoStep);
|
|
|
|
|
connect(m_btn_step_over, &QAbstractButton::clicked, [this]() { DoStep(true); });
|
|
|
|
|
|
|
|
|
|
connect(m_btn_run, &QAbstractButton::clicked, [this]()
|
|
|
|
|
{
|
|
|
|
|
if (const auto cpu = get_cpu())
|
|
|
|
|
{
|
|
|
|
|
// If paused, unpause.
|
|
|
|
|
// If not paused, add dbg_pause.
|
|
|
|
|
const auto old = cpu->state.fetch_op([](bs_t<cpu_flag>& state)
|
|
|
|
|
{
|
|
|
|
|
if (state & s_pause_flags)
|
|
|
|
|
{
|
|
|
|
|
state -= s_pause_flags;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state += cpu_flag::dbg_pause;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Notify only if no pause flags are set after this change
|
|
|
|
|
if (old & s_pause_flags)
|
|
|
|
|
{
|
|
|
|
|
if (g_debugger_pause_all_threads_on_bp && Emu.IsPaused() && (old & s_pause_flags) == s_pause_flags)
|
|
|
|
|
{
|
|
|
|
|
// Resume all threads were paused by this breakpoint
|
|
|
|
|
Emu.Resume();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpu->state.notify_one(s_pause_flags);
|
|
|
|
|
m_debugger_list->EnableThreadFollowing();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Tighten up, put the debugger on a wary watch over any thread info changes if there aren't any
|
|
|
|
|
// This allows responsive debugger interaction
|
|
|
|
|
m_ui_fast_update_permission_deadline = m_ui_update_ctr + 5;
|
|
|
|
|
});
|
|
|
|
|
connect(m_btn_run, &QAbstractButton::clicked, this, &debugger_frame::RunBtnPress);
|
|
|
|
|
|
|
|
|
|
connect(m_choice_units->lineEdit(), &QLineEdit::editingFinished, [&]
|
|
|
|
|
{
|
|
|
|
@@ -1156,6 +1121,20 @@ void debugger_frame::DoStep(bool step_over)
|
|
|
|
|
m_debugger_list->ShowAddress(cpu->get_pc() + 4, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (step_over && cpu->id_type() == 0x55)
|
|
|
|
|
{
|
|
|
|
|
const bool was_paused = cpu->is_paused();
|
|
|
|
|
static_cast<rsx::thread*>(cpu)->pause_on_draw = true;
|
|
|
|
|
|
|
|
|
|
if (was_paused)
|
|
|
|
|
{
|
|
|
|
|
RunBtnPress();
|
|
|
|
|
m_debugger_list->EnableThreadFollowing(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (const auto _state = +cpu->state; _state & s_pause_flags && _state & cpu_flag::wait && !(_state & cpu_flag::dbg_step))
|
|
|
|
|
{
|
|
|
|
|
if (should_step_over)
|
|
|
|
@@ -1166,7 +1145,7 @@ void debugger_frame::DoStep(bool step_over)
|
|
|
|
|
const u32 next_instruction_pc = current_instruction_pc + 4;
|
|
|
|
|
m_ppu_breakpoint_handler->AddBreakpoint(next_instruction_pc);
|
|
|
|
|
|
|
|
|
|
// Undefine previous step over breakpoint if it hasnt been already
|
|
|
|
|
// Undefine previous step over breakpoint if it hasn't been already
|
|
|
|
|
// This can happen when the user steps over a branch that doesn't return to itself
|
|
|
|
|
if (m_last_step_over_breakpoint != umax)
|
|
|
|
|
{
|
|
|
|
@@ -1204,6 +1183,43 @@ void debugger_frame::EnableUpdateTimer(bool enable) const
|
|
|
|
|
enable ? m_update->start(10) : m_update->stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void debugger_frame::RunBtnPress()
|
|
|
|
|
{
|
|
|
|
|
if (const auto cpu = get_cpu())
|
|
|
|
|
{
|
|
|
|
|
// If paused, unpause.
|
|
|
|
|
// If not paused, add dbg_pause.
|
|
|
|
|
const auto old = cpu->state.fetch_op([](bs_t<cpu_flag>& state)
|
|
|
|
|
{
|
|
|
|
|
if (state & s_pause_flags)
|
|
|
|
|
{
|
|
|
|
|
state -= s_pause_flags;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state += cpu_flag::dbg_pause;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Notify only if no pause flags are set after this change
|
|
|
|
|
if (old & s_pause_flags)
|
|
|
|
|
{
|
|
|
|
|
if (g_debugger_pause_all_threads_on_bp && Emu.IsPaused() && (old & s_pause_flags) == s_pause_flags)
|
|
|
|
|
{
|
|
|
|
|
// Resume all threads were paused by this breakpoint
|
|
|
|
|
Emu.Resume();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpu->state.notify_one(s_pause_flags);
|
|
|
|
|
m_debugger_list->EnableThreadFollowing();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Tighten up, put the debugger on a wary watch over any thread info changes if there aren't any
|
|
|
|
|
// This allows responsive debugger interaction
|
|
|
|
|
m_ui_fast_update_permission_deadline = m_ui_update_ctr + 5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void debugger_frame::EnableButtons(bool enable)
|
|
|
|
|
{
|
|
|
|
|
const auto cpu = get_cpu();
|
|
|
|
|