Add 'expressions' to MemoryVisualizer's "size" field.

This commit is contained in:
Ernie Pasveer
2024-11-10 12:40:43 -06:00
parent 32514469f5
commit c586a2151b
13 changed files with 123 additions and 20 deletions
+2
View File
@@ -14,6 +14,8 @@
* Show stack as a hex dump, with options to view as short, int, long, ascii, ...
* The "go to address" in the Assembly view now works if address it outside
current assembly view.
* MemoryVisualizer. Dump size now takes a gdb expression. So it can be a value,
mathimatical expression, or the return value of 'function()'.
## [2.4] - 2024-03-18
* Changed main icon to a more license friendly one.
+2
View File
@@ -129,6 +129,7 @@ set(HEADER_FILES
SeerProgressIndicator.h
SeerMessagesDialog.h
SeerAssemblyPreferenceDialog.h
SeerHistoryLineEdit.h
QProcessInfo.h
QProcessInfoWidget.h
QProgressIndicator.h
@@ -227,6 +228,7 @@ set(SOURCE_FILES
SeerProgressIndicator.cpp
SeerMessagesDialog.cpp
SeerAssemblyPreferenceDialog.cpp
SeerHistoryLineEdit.cpp
QProcessInfo.cpp
QProcessInfoWidget.cpp
QProgressIndicator.cpp
+12
View File
@@ -0,0 +1,12 @@
#include "SeerHistoryLineEdit.h"
SeerHistoryLineEdit::SeerHistoryLineEdit (const QString& contents, QWidget* parent) : QHistoryLineEdit(contents, parent) {
QObject::connect(this, &QHistoryLineEdit::lostFocus, this, &QHistoryLineEdit::execute);
}
SeerHistoryLineEdit::SeerHistoryLineEdit (QWidget* parent) : QHistoryLineEdit(parent) {
QObject::connect(this, &QHistoryLineEdit::lostFocus, this, &QHistoryLineEdit::execute);
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "QHistoryLineEdit.h"
//
// Extends QHistoryLineEdit to connect the 'lostFocus' signal with the
// 'execute' slot. This adds the current text to the history when
// focus is lost.
//
class SeerHistoryLineEdit : public QHistoryLineEdit {
Q_OBJECT
public:
SeerHistoryLineEdit(const QString& contents, QWidget* parent = 0);
SeerHistoryLineEdit(QWidget* parent = 0);
};
+58 -13
View File
@@ -15,9 +15,10 @@
SeerMemoryVisualizerWidget::SeerMemoryVisualizerWidget (QWidget* parent) : QWidget(parent) {
// Init variables.
_variableId = Seer::createID(); // Create two id's for queries.
_memoryId = Seer::createID();
_asmId = Seer::createID();
_variableId = Seer::createID(); // Create id's for queries.
_memoryId = Seer::createID();
_memoryLengthId = Seer::createID();
_asmId = Seer::createID();
// Set up UI.
setupUi(this);
@@ -27,7 +28,6 @@ SeerMemoryVisualizerWidget::SeerMemoryVisualizerWidget (QWidget* parent) : QWidg
setWindowTitle("Seer Memory Visualizer");
setAttribute(Qt::WA_DeleteOnClose);
memoryLengthLineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression("\\s*([1-9]\\d*\\s*)+"), this));
columnCountSpinBox->setValue(memoryHexEditor->bytesPerLine());
if (memoryHexEditor->memoryMode() == SeerHexWidget::HexMemoryMode) {
@@ -57,15 +57,17 @@ SeerMemoryVisualizerWidget::SeerMemoryVisualizerWidget (QWidget* parent) : QWidg
}
// Connect things.
QObject::connect(refreshToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handleRefreshButton);
QObject::connect(helpToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handleHelpButton);
QObject::connect(memoryLengthLineEdit, &QLineEdit::returnPressed, this, &SeerMemoryVisualizerWidget::handleRefreshButton);
QObject::connect(variableNameLineEdit, &QLineEdit::returnPressed, this, &SeerMemoryVisualizerWidget::handleVariableNameLineEdit);
QObject::connect(memoryDisplayFormatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SeerMemoryVisualizerWidget::handleMemoryDisplayFormatComboBox);
QObject::connect(charDisplayFormatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SeerMemoryVisualizerWidget::handleCharDisplayFormatComboBox);
QObject::connect(columnCountSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &SeerMemoryVisualizerWidget::handleColumnCountSpinBox);
QObject::connect(printToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handlePrintButton);
QObject::connect(saveToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handleSaveButton);
QObject::connect(refreshToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handleRefreshButton);
QObject::connect(helpToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handleHelpButton);
QObject::connect(variableNameLineEdit, &SeerHistoryLineEdit::returnPressed, this, &SeerMemoryVisualizerWidget::handleVariableNameLineEdit);
QObject::connect(variableNameLineEdit, &SeerHistoryLineEdit::editingFinished, this, &SeerMemoryVisualizerWidget::handleVariableNameLineEdit);
QObject::connect(memoryLengthLineEdit, &SeerHistoryLineEdit::returnPressed, this, &SeerMemoryVisualizerWidget::handleRefreshButton);
QObject::connect(memoryLengthLineEdit, &SeerHistoryLineEdit::editingFinished, this, &SeerMemoryVisualizerWidget::handleMemoryLengthLineEdit);
QObject::connect(memoryDisplayFormatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SeerMemoryVisualizerWidget::handleMemoryDisplayFormatComboBox);
QObject::connect(charDisplayFormatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SeerMemoryVisualizerWidget::handleCharDisplayFormatComboBox);
QObject::connect(columnCountSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &SeerMemoryVisualizerWidget::handleColumnCountSpinBox);
QObject::connect(printToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handlePrintButton);
QObject::connect(saveToolButton, &QToolButton::clicked, this, &SeerMemoryVisualizerWidget::handleSaveButton);
// Restore window settings.
readSettings();
@@ -149,6 +151,16 @@ QString SeerMemoryVisualizerWidget::variableAddress () const {
return variableAddressLineEdit->text();
}
void SeerMemoryVisualizerWidget::setMemoryLength (const QString& length) {
memoryLengthLineEdit->setText(length);
}
QString SeerMemoryVisualizerWidget::memoryLength () const {
return memoryLengthLineEdit->text();
}
void SeerMemoryVisualizerWidget::handleText (const QString& text) {
QApplication::setOverrideCursor(Qt::BusyCursor);
@@ -189,6 +201,15 @@ void SeerMemoryVisualizerWidget::handleText (const QString& text) {
// Set the variable address.
setVariableAddress(address);
}else if (id_text.toInt() == _memoryLengthId) {
// Set the memory length.
QString value_text = Seer::parseFirst(text, "value=", '"', '"', false);
setMemoryLength(value_text);
handleRefreshButton();
}
}else if (text.contains(QRegularExpression("^([0-9]+)\\^done,memory="))) {
@@ -247,6 +268,7 @@ void SeerMemoryVisualizerWidget::handleText (const QString& text) {
if (id_text.toInt() == _variableId) {
variableAddressLineEdit->setText( Seer::filterEscapes(Seer::parseFirst(text, "msg=", '"', '"', false)) );
variableAddressLineEdit->setFocus();
}
if (id_text.toInt() == _memoryId) {
@@ -258,6 +280,16 @@ void SeerMemoryVisualizerWidget::handleText (const QString& text) {
}
}
if (id_text.toInt() == _memoryLengthId) {
// Display the error message.
QString msg_text = Seer::parseFirst(text, "msg=", false);
QMessageBox::warning(this, "Error.", Seer::filterEscapes(msg_text));
memoryLengthLineEdit->setText("");
memoryLengthLineEdit->setFocus();
}
// At a stopping point, refresh.
}else if (text.startsWith("*stopped,reason=\"")) {
@@ -292,6 +324,10 @@ void SeerMemoryVisualizerWidget::handleRefreshButton () {
nbytes = memoryLengthLineEdit->text().toInt();
}
if (nbytes < 1) {
return;
}
emit evaluateMemoryExpression(_memoryId, variableAddressLineEdit->text(), nbytes);
emit evaluateAsmExpression(_asmId, variableAddressLineEdit->text(), nbytes, 2);
}
@@ -309,6 +345,15 @@ void SeerMemoryVisualizerWidget::handleVariableNameLineEdit () {
setVariableName (variableNameLineEdit->text());
}
void SeerMemoryVisualizerWidget::handleMemoryLengthLineEdit () {
if (memoryLengthLineEdit->text() == "") {
return;
}
emit evaluateVariableExpression(_memoryLengthId, memoryLengthLineEdit->text());
}
void SeerMemoryVisualizerWidget::handleMemoryDisplayFormatComboBox (int index) {
if (index == 0) {
+4
View File
@@ -15,6 +15,8 @@ class SeerMemoryVisualizerWidget : public QWidget, protected Ui::SeerMemoryVisua
QString variableName () const;
void setVariableAddress (const QString& address);
QString variableAddress () const;
void setMemoryLength (const QString& length);
QString memoryLength () const;
signals:
void evaluateVariableExpression (int expressionid, QString expression);
@@ -28,6 +30,7 @@ class SeerMemoryVisualizerWidget : public QWidget, protected Ui::SeerMemoryVisua
void handleRefreshButton ();
void handleHelpButton ();
void handleVariableNameLineEdit ();
void handleMemoryLengthLineEdit ();
void handleMemoryDisplayFormatComboBox (int index);
void handleCharDisplayFormatComboBox (int index);
void handleColumnCountSpinBox (int value);
@@ -42,6 +45,7 @@ class SeerMemoryVisualizerWidget : public QWidget, protected Ui::SeerMemoryVisua
private:
int _variableId;
int _memoryId;
int _memoryLengthId;
int _asmId;
};
+4 -4
View File
@@ -17,7 +17,7 @@
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QHistoryLineEdit" name="variableNameLineEdit">
<widget class="SeerHistoryLineEdit" name="variableNameLineEdit">
<property name="toolTip">
<string>Variable expression resulting in an address.</string>
</property>
@@ -43,7 +43,7 @@
</widget>
</item>
<item>
<widget class="QHistoryLineEdit" name="memoryLengthLineEdit">
<widget class="SeerHistoryLineEdit" name="memoryLengthLineEdit">
<property name="toolTip">
<string>Number of bytes to display.</string>
</property>
@@ -269,9 +269,9 @@
<container>1</container>
</customwidget>
<customwidget>
<class>QHistoryLineEdit</class>
<class>SeerHistoryLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">QHistoryLineEdit.h</header>
<header location="global">SeerHistoryLineEdit.h</header>
</customwidget>
</customwidgets>
<resources>
+5
View File
@@ -54,6 +54,11 @@ It can also be one of gdb' special variables. Like the program counter. Enter it
### Number of bytes entry field
The default number of bytes to display is 256. Fewer or more than this number can be entered.
This can take a gdb expression.
* A value. '100'
* An expression. '100+50'
* The result of a function in the program. 'myarraysize()'
### Display format.
Binary file not shown.
+2 -2
View File
@@ -4,10 +4,10 @@ all: helloworld
# This rule tells make how to build the test program
helloworld: helloworld.cpp
g++ -g -o helloworld helloworld.cpp function1.cpp
g++ -g -o helloworld helloworld.cpp function1.cpp valueoflife.cpp
# This rule tells make to clean things
.PHONY: clean
clean:
rm -f helloworld helloworld.o function1.o
rm -f helloworld helloworld.o function1.o valueoflife.o
+2 -1
View File
@@ -9,7 +9,8 @@
// message == say hi to the world.
// function1 == a function to call to simulate work.
void function1 (const std::string& message);
void function1 (const std::string& message);
int valueoflife ();
int main (int argc, char** argv) {
+9
View File
@@ -0,0 +1,9 @@
#include "valueoflife.h"
int valueoflife () {
int i = 42;
return i;
}
+4
View File
@@ -0,0 +1,4 @@
#pragma once
int valueoflife ();