Debugger: Avoid resetting symbol trees while single stepping

This commit is contained in:
chaoticgd 2024-10-21 06:19:38 +01:00 committed by Ty
parent 56a2b3b5ad
commit 7d63a9e51c
3 changed files with 76 additions and 7 deletions

View File

@ -164,10 +164,6 @@ void CpuWidget::setupSymbolTrees()
m_ui.tabLocalVariables->layout()->addWidget(m_local_variable_tree);
m_ui.tabParameterVariables->layout()->addWidget(m_parameter_variable_tree);
connect(m_ui.tabWidgetRegFunc, &QTabWidget::currentChanged, m_function_tree, &SymbolTreeWidget::updateModel);
connect(m_ui.tabWidget, &QTabWidget::currentChanged, m_global_variable_tree, &SymbolTreeWidget::updateModel);
connect(m_ui.tabWidget, &QTabWidget::currentChanged, m_local_variable_tree, &SymbolTreeWidget::updateModel);
connect(m_function_tree, &SymbolTreeWidget::goToInDisassembly, m_ui.disassemblyWidget, &DisassemblyWidget::gotoAddressAndSetFocus);
connect(m_global_variable_tree, &SymbolTreeWidget::goToInDisassembly, m_ui.disassemblyWidget, &DisassemblyWidget::gotoAddressAndSetFocus);
connect(m_local_variable_tree, &SymbolTreeWidget::goToInDisassembly, m_ui.disassemblyWidget, &DisassemblyWidget::gotoAddressAndSetFocus);
@ -207,8 +203,10 @@ void CpuWidget::reloadCPUWidgets()
m_ui.disassemblyWidget->update();
m_ui.memoryviewWidget->update();
m_local_variable_tree->reset();
m_parameter_variable_tree->reset();
m_function_tree->updateModel();
m_global_variable_tree->updateModel();
m_local_variable_tree->updateModel();
m_parameter_variable_tree->updateModel();
}
void CpuWidget::paintEvent(QPaintEvent* event)

View File

@ -60,7 +60,7 @@ void SymbolTreeWidget::resizeEvent(QResizeEvent* event)
void SymbolTreeWidget::updateModel()
{
if (!m_model || m_model->needsReset())
if (needsReset())
reset();
else
updateVisibleNodes(true);
@ -489,6 +489,11 @@ void SymbolTreeWidget::openMenu(QPoint pos)
m_context_menu->exec(m_ui.treeView->viewport()->mapToGlobal(pos));
}
bool SymbolTreeWidget::needsReset() const
{
return !m_model || m_model->needsReset();
}
void SymbolTreeWidget::onDeleteButtonPressed()
{
SymbolTreeNode* node = currentNode();
@ -885,14 +890,43 @@ LocalVariableTreeWidget::LocalVariableTreeWidget(DebugInterface& cpu, QWidget* p
LocalVariableTreeWidget::~LocalVariableTreeWidget() = default;
bool LocalVariableTreeWidget::needsReset() const
{
if (!m_function.valid())
return true;
u32 program_counter = m_cpu.getPC();
bool left_function = true;
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
const ccc::Function* function = database.functions.symbol_from_handle(m_function);
if (!function || !function->address().valid())
return;
u32 begin = function->address().value;
u32 end = function->address().value + function->size();
left_function = program_counter < begin || program_counter >= end;
});
if (left_function)
return true;
return SymbolTreeWidget::needsReset();
}
std::vector<SymbolTreeWidget::SymbolWork> LocalVariableTreeWidget::getSymbols(
const QString& filter, const ccc::SymbolDatabase& database)
{
u32 program_counter = m_cpu.getPC();
const ccc::Function* function = database.functions.symbol_overlapping_address(program_counter);
if (!function || !function->local_variables().has_value())
{
m_function = ccc::FunctionHandle();
return std::vector<SymbolWork>();
}
m_function = function->handle();
m_caller_stack_pointer = m_cpu.getCallerStackPointer(*function);
std::vector<SymbolTreeWidget::SymbolWork> symbols;
@ -981,6 +1015,31 @@ ParameterVariableTreeWidget::ParameterVariableTreeWidget(DebugInterface& cpu, QW
ParameterVariableTreeWidget::~ParameterVariableTreeWidget() = default;
bool ParameterVariableTreeWidget::needsReset() const
{
if (!m_function.valid())
return true;
u32 program_counter = m_cpu.getPC();
bool left_function = true;
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
const ccc::Function* function = database.functions.symbol_from_handle(m_function);
if (!function || !function->address().valid())
return;
u32 begin = function->address().value;
u32 end = function->address().value + function->size();
left_function = program_counter < begin || program_counter >= end;
});
if (left_function)
return true;
return SymbolTreeWidget::needsReset();
}
std::vector<SymbolTreeWidget::SymbolWork> ParameterVariableTreeWidget::getSymbols(
const QString& filter, const ccc::SymbolDatabase& database)
{
@ -989,8 +1048,12 @@ std::vector<SymbolTreeWidget::SymbolWork> ParameterVariableTreeWidget::getSymbol
u32 program_counter = m_cpu.getPC();
const ccc::Function* function = database.functions.symbol_overlapping_address(program_counter);
if (!function || !function->parameter_variables().has_value())
{
m_function = ccc::FunctionHandle();
return std::vector<SymbolWork>();
}
m_function = function->handle();
m_caller_stack_pointer = m_cpu.getCallerStackPointer(*function);
for (const ccc::ParameterVariableHandle parameter_variable_handle : *function->parameter_variables())

View File

@ -72,6 +72,8 @@ protected:
void setupMenu();
void openMenu(QPoint pos);
virtual bool needsReset() const;
virtual std::vector<SymbolWork> getSymbols(
const QString& filter, const ccc::SymbolDatabase& database) = 0;
@ -172,6 +174,8 @@ public:
virtual ~LocalVariableTreeWidget();
protected:
bool needsReset() const override;
std::vector<SymbolWork> getSymbols(
const QString& filter, const ccc::SymbolDatabase& database) override;
@ -182,6 +186,7 @@ protected:
void onNewButtonPressed() override;
ccc::FunctionHandle m_function;
std::optional<u32> m_caller_stack_pointer;
};
@ -193,6 +198,8 @@ public:
virtual ~ParameterVariableTreeWidget();
protected:
bool needsReset() const override;
std::vector<SymbolWork> getSymbols(
const QString& filter, const ccc::SymbolDatabase& database) override;
@ -203,6 +210,7 @@ protected:
void onNewButtonPressed() override;
ccc::FunctionHandle m_function;
std::optional<u32> m_caller_stack_pointer;
};