Compare commits

...

2 Commits

Author SHA1 Message Date
Ernie Pasveer a465cd5a1a Merge pull request #518 from tiresiasfromthebai/fix-visualizer-stale-address
Re-evaluate the visualized variable's address on refresh
2026-08-13 12:14:02 -05:00
tiresiasfromthebai 84f7d81ea9 Re-evaluate the visualized variable's address on refresh
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.
2026-08-13 13:29:07 +02:00
4 changed files with 75 additions and 8 deletions
+49 -7
View File
@@ -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);
+2
View File
@@ -76,6 +76,8 @@ class SeerArrayVisualizerWidget : public QWidget, protected Ui::SeerArrayVisuali
void resizeEvent (QResizeEvent* event);
private:
void readaMemory ();
void readbMemory ();
void createASeries ();
void createBSeries ();
+22 -1
View File
@@ -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);
+2
View File
@@ -55,6 +55,8 @@ class SeerMatrixVisualizerWidget : public QWidget, protected Ui::SeerMatrixVisua
void resizeEvent (QResizeEvent* event);
private:
void readMemory ();
int _variableId;
int _memoryId;
int _rowsId;