From 84f7d81ea9ee9b6deddb06f99aa50426a12f59b0 Mon Sep 17 00:00:00 2001 From: tiresiasfromthebai Date: Thu, 13 Aug 2026 10:16:28 +0200 Subject: [PATCH] Re-evaluate the visualized variable's address on refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Array and Matrix visualizers evaluated the variable's address only when the name was typed; every refresh then re-read memory at that stored address forever. A stale address (a vector entered before its construction, a reallocation, a re-run) kept being read — errors at best, plausible-looking dead data at worst. Split the refresh in two: the refresh handlers now re-evaluate the variable name, and the answer reads the memory at the fresh address (readaMemory/readbMemory/readMemory). Every refresh path — the manual button, the auto-refresh at each stop, and the length/offset/stride changes — now goes through the re-evaluation. The read is skipped for a null address or an empty length, so a not-yet-constructed variable shows its 0x0 address quietly instead of raising memory errors. --- src/SeerArrayVisualizerWidget.cpp | 56 ++++++++++++++++++++++++++---- src/SeerArrayVisualizerWidget.h | 2 ++ src/SeerMatrixVisualizerWidget.cpp | 23 +++++++++++- src/SeerMatrixVisualizerWidget.h | 2 ++ 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/SeerArrayVisualizerWidget.cpp b/src/SeerArrayVisualizerWidget.cpp index e5d0694..8cc0712 100644 --- a/src/SeerArrayVisualizerWidget.cpp +++ b/src/SeerArrayVisualizerWidget.cpp @@ -430,8 +430,10 @@ void SeerArrayVisualizerWidget::handleText (const QString& text) { } } - // Set the variable address. + // Set the variable address and read the memory there. setAVariableAddress(address); + + readaMemory(); } if (id_text.toInt() == _aLengthId) { @@ -489,8 +491,10 @@ void SeerArrayVisualizerWidget::handleText (const QString& text) { } } - // Set the variable address. + // Set the variable address and read the memory there. setBVariableAddress(address); + + readbMemory(); } if (id_text.toInt() == _bLengthId) { @@ -742,6 +746,26 @@ void SeerArrayVisualizerWidget::handleaRefreshButton () { return; } + // Re-evaluate the variable's address first: it may have changed since the + // last stop (or the variable may not have existed yet). The answer then + // reads the memory at the fresh address. See readaMemory(). + emit evaluateVariableExpression(_aVariableId, aVariableNameLineEdit->text()); +} + +void SeerArrayVisualizerWidget::handlebRefreshButton () { + + if (bVariableNameLineEdit->text() == "") { + return; + } + + // Re-evaluate the variable's address first: it may have changed since the + // last stop (or the variable may not have existed yet). The answer then + // reads the memory at the fresh address. See readbMemory(). + emit evaluateVariableExpression(_bVariableId, bVariableNameLineEdit->text()); +} + +void SeerArrayVisualizerWidget::readaMemory () { + if (aVariableAddressLineEdit->text() == "") { return; } @@ -750,18 +774,25 @@ void SeerArrayVisualizerWidget::handleaRefreshButton () { return; } + // A null address can't be read (a std::vector before its construction, + // for example). Keep the "0x0" visible but don't ask gdb. + if (aVariableAddressLineEdit->text() == "0x0") { + return; + } + int bytes = aArrayLengthLineEdit->text().toInt() * Seer::typeBytes(aArrayDisplayFormatComboBox->currentText()); + // Nothing to read yet (no length). + if (bytes <= 0) { + return; + } + //qDebug() << _aMemoryId << aVariableAddressLineEdit->text() << aArrayLengthLineEdit->text() << aArrayDisplayFormatComboBox->currentText() << bytes; emit evaluateMemoryExpression(_aMemoryId, aVariableAddressLineEdit->text(), bytes); } -void SeerArrayVisualizerWidget::handlebRefreshButton () { - - if (bVariableNameLineEdit->text() == "") { - return; - } +void SeerArrayVisualizerWidget::readbMemory () { if (bVariableAddressLineEdit->text() == "") { return; @@ -771,8 +802,19 @@ void SeerArrayVisualizerWidget::handlebRefreshButton () { return; } + // A null address can't be read (a std::vector before its construction, + // for example). Keep the "0x0" visible but don't ask gdb. + if (bVariableAddressLineEdit->text() == "0x0") { + return; + } + int bytes = bArrayLengthLineEdit->text().toInt() * Seer::typeBytes(bArrayDisplayFormatComboBox->currentText()); + // Nothing to read yet (no length). + if (bytes <= 0) { + return; + } + //qDebug() << _bMemoryId << bVariableAddressLineEdit->text() << bArrayLengthLineEdit->text() << bArrayDisplayFormatComboBox->currentText() << bytes; emit evaluateMemoryExpression(_bMemoryId, bVariableAddressLineEdit->text(), bytes); diff --git a/src/SeerArrayVisualizerWidget.h b/src/SeerArrayVisualizerWidget.h index f131901..1a90330 100644 --- a/src/SeerArrayVisualizerWidget.h +++ b/src/SeerArrayVisualizerWidget.h @@ -76,6 +76,8 @@ class SeerArrayVisualizerWidget : public QWidget, protected Ui::SeerArrayVisuali void resizeEvent (QResizeEvent* event); private: + void readaMemory (); + void readbMemory (); void createASeries (); void createBSeries (); diff --git a/src/SeerMatrixVisualizerWidget.cpp b/src/SeerMatrixVisualizerWidget.cpp index 27a1764..de22f48 100644 --- a/src/SeerMatrixVisualizerWidget.cpp +++ b/src/SeerMatrixVisualizerWidget.cpp @@ -238,8 +238,10 @@ void SeerMatrixVisualizerWidget::handleText (const QString& text) { } } - // Set the variable address. + // Set the variable address and read the memory there. setVariableAddress(address); + + readMemory(); } if (id_text.toInt() == _rowsId) { @@ -436,6 +438,14 @@ void SeerMatrixVisualizerWidget::handleRefreshButton () { return; } + // Re-evaluate the variable's address first: it may have changed since the + // last stop (or the variable may not have existed yet). The answer then + // reads the memory at the fresh address. See readMemory(). + emit evaluateVariableExpression(_variableId, variableNameLineEdit->text()); +} + +void SeerMatrixVisualizerWidget::readMemory () { + if (variableAddressLineEdit->text() == "") { return; } @@ -444,8 +454,19 @@ void SeerMatrixVisualizerWidget::handleRefreshButton () { return; } + // A null address can't be read (a matrix before its construction, for + // example). Keep the "0x0" visible but don't ask gdb. + if (variableAddressLineEdit->text() == "0x0") { + return; + } + int bytes = matrixRowsLineEdit->text().toInt() * matrixColumnsLineEdit->text().toInt() * Seer::typeBytes(matrixDisplayFormatComboBox->currentText()); + // Nothing to read yet (no rows/columns). + if (bytes <= 0) { + return; + } + // qDebug() << "Asking for" << bytes << "bytes of matrix data."; emit evaluateMemoryExpression(_memoryId, variableAddressLineEdit->text(), bytes); diff --git a/src/SeerMatrixVisualizerWidget.h b/src/SeerMatrixVisualizerWidget.h index a2be055..6799edc 100644 --- a/src/SeerMatrixVisualizerWidget.h +++ b/src/SeerMatrixVisualizerWidget.h @@ -55,6 +55,8 @@ class SeerMatrixVisualizerWidget : public QWidget, protected Ui::SeerMatrixVisua void resizeEvent (QResizeEvent* event); private: + void readMemory (); + int _variableId; int _memoryId; int _rowsId;