mirror of
https://github.com/epasveer/seer.git
synced 2026-08-29 16:40:42 +08:00
Add 'expressions' to MemoryVisualizer's "size" field.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "valueoflife.h"
|
||||
|
||||
int valueoflife () {
|
||||
|
||||
int i = 42;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
int valueoflife ();
|
||||
|
||||
Reference in New Issue
Block a user