debugger: Fix use of invalid pointers

This commit is contained in:
Eladash 2023-06-04 17:04:22 +03:00 committed by Ivan
parent c85775922e
commit e77c01d00a
2 changed files with 51 additions and 16 deletions

View File

@ -767,25 +767,56 @@ cpu_thread* debugger_frame::get_cpu()
return m_rsx; return m_rsx;
} }
std::function<cpu_thread*()> debugger_frame::make_check_cpu(cpu_thread* cpu) std::function<cpu_thread*()> debugger_frame::make_check_cpu(cpu_thread* cpu, bool unlocked)
{ {
const u32 id = cpu ? cpu->id : umax; const u32 id = cpu ? cpu->id : umax;
const u32 type = id >> 24; const u32 type = id >> 24;
std::shared_ptr<cpu_thread> shared = type == 1 ? static_cast<std::shared_ptr<cpu_thread>>(idm::get<named_thread<ppu_thread>>(id)) : std::shared_ptr<cpu_thread> shared;
type == 2 ? idm::get<named_thread<spu_thread>>(id) : nullptr;
if (g_fxo->is_init<id_manager::id_map<named_thread<ppu_thread>>>() && g_fxo->is_init<id_manager::id_map<named_thread<spu_thread>>>())
{
if (unlocked)
{
if (type == 1)
{
shared = idm::get_unlocked<named_thread<ppu_thread>>(id);
}
else if (type == 2)
{
shared = idm::get_unlocked<named_thread<spu_thread>>(id);
}
}
else
{
if (type == 1)
{
shared = idm::get<named_thread<ppu_thread>>(id);
}
else if (type == 2)
{
shared = idm::get<named_thread<spu_thread>>(id);
}
}
}
if (shared.get() != cpu) if (shared.get() != cpu)
{ {
shared.reset(); shared.reset();
} }
return [&rsx = m_rsx, cpu, type, shared = std::move(shared)]() -> cpu_thread* return [cpu, type, shared = std::move(shared), emu_course = Emu.ProcureCurrentEmulationCourseInformation()]() -> cpu_thread*
{ {
if (emu_course != Emu.ProcureCurrentEmulationCourseInformation())
{
// Invalidate all data after Emu.Kill()
return nullptr;
}
if (type == 1 || type == 2) if (type == 1 || type == 2)
{ {
// SPU and PPU // SPU and PPU
if (!shared || (shared->state & cpu_flag::exit && shared->state & cpu_flag::wait)) if (!shared || shared->state.all_of(cpu_flag::exit + cpu_flag::wait))
{ {
return nullptr; return nullptr;
} }
@ -794,7 +825,7 @@ std::function<cpu_thread*()> debugger_frame::make_check_cpu(cpu_thread* cpu)
} }
// RSX // RSX
if (rsx == cpu) if (g_fxo->try_get<rsx::thread>() == cpu)
{ {
return cpu; return cpu;
} }
@ -874,7 +905,7 @@ void debugger_frame::UpdateUI()
m_ui_update_ctr++; m_ui_update_ctr++;
} }
using data_type = std::pair<cpu_thread*, u32>; using data_type = std::function<cpu_thread*()>;
Q_DECLARE_METATYPE(data_type); Q_DECLARE_METATYPE(data_type);
@ -896,21 +927,18 @@ void debugger_frame::UpdateUnitList()
return; return;
} }
//const int old_size = m_choice_units->count();
QVariant old_cpu = m_choice_units->currentData(); QVariant old_cpu = m_choice_units->currentData();
bool reselected = false; bool reselected = false;
const auto on_select = [&](u32 id, cpu_thread& cpu) const auto on_select = [&](u32 id, cpu_thread& cpu)
{ {
if (emu_state == system_state::stopped) return; const QVariant var_cpu = QVariant::fromValue<data_type>(make_check_cpu(std::addressof(cpu), true));
const QVariant var_cpu = QVariant::fromValue<data_type>(std::make_pair(&cpu, id));
// Space at the end is to pad a gap on the right // Space at the end is to pad a gap on the right
m_choice_units->addItem(qstr((id >> 24 == 0x55 ? "RSX[0x55555555]" : cpu.get_name()) + ' '), var_cpu); m_choice_units->addItem(qstr((id >> 24 == 0x55 ? "RSX[0x55555555]" : cpu.get_name()) + ' '), var_cpu);
if (!reselected && old_cpu == var_cpu) if (!reselected && old_cpu.canConvert<data_type>() && old_cpu.value<data_type>()() == std::addressof(cpu))
{ {
m_choice_units->setCurrentIndex(m_choice_units->count() - 1); m_choice_units->setCurrentIndex(m_choice_units->count() - 1);
reselected = true; reselected = true;
@ -923,8 +951,11 @@ void debugger_frame::UpdateUnitList()
m_choice_units->clear(); m_choice_units->clear();
m_choice_units->addItem(NoThreadString); m_choice_units->addItem(NoThreadString);
idm::select<named_thread<ppu_thread>>(on_select); if (emu_state != system_state::stopped)
idm::select<named_thread<spu_thread>>(on_select); {
idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);
}
if (const auto render = g_fxo->try_get<rsx::thread>(); emu_state != system_state::stopped && render && render->ctrl) if (const auto render = g_fxo->try_get<rsx::thread>(); emu_state != system_state::stopped && render && render->ctrl)
{ {
@ -953,7 +984,9 @@ void debugger_frame::UpdateUnitList()
void debugger_frame::OnSelectUnit() void debugger_frame::OnSelectUnit()
{ {
auto [selected, cpu_id] = m_choice_units->currentData().value<data_type>(); const QVariant data = m_choice_units->currentData();
cpu_thread* selected = data.canConvert<data_type>() ? data.value<data_type>()() : nullptr;
if (m_emu_state != system_state::stopped) if (m_emu_state != system_state::stopped)
{ {
@ -984,6 +1017,8 @@ void debugger_frame::OnSelectUnit()
if (selected) if (selected)
{ {
const u32 cpu_id = selected->id;
switch (cpu_id >> 24) switch (cpu_id >> 24)
{ {
case 1: case 1:

View File

@ -76,7 +76,7 @@ class debugger_frame : public custom_dock_widget
std::shared_ptr<gui_settings> m_gui_settings; std::shared_ptr<gui_settings> m_gui_settings;
cpu_thread* get_cpu(); cpu_thread* get_cpu();
std::function<cpu_thread*()> make_check_cpu(cpu_thread* cpu); std::function<cpu_thread*()> make_check_cpu(cpu_thread* cpu, bool unlocked = false);
void open_breakpoints_settings(); void open_breakpoints_settings();
public: public: