diff --git a/CHANGELOG.md b/CHANGELOG.md index 120885d..62e087d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ * Improved handling of \n \t and other escaped characters in gdb log window. * Show breakpoint info as a tooltip if the breakpoint icon is clicked with LMB and held down. -* Show stack as a hex dump, with options to view as short, int, long, ... +* Show stack as a hex dump, with options to view as short, int, long, ascii, ... ## [2.4] - 2024-03-18 * Changed main icon to a more license friendly one. diff --git a/src/SeerStackDumpBrowserWidget.cpp b/src/SeerStackDumpBrowserWidget.cpp index deea4e6..9d2d3d6 100644 --- a/src/SeerStackDumpBrowserWidget.cpp +++ b/src/SeerStackDumpBrowserWidget.cpp @@ -7,6 +7,7 @@ #include #include #include +#include SeerStackDumpBrowserWidget::SeerStackDumpBrowserWidget (QWidget* parent) : QWidget(parent) { @@ -32,10 +33,11 @@ SeerStackDumpBrowserWidget::SeerStackDumpBrowserWidget (QWidget* parent) : QWidg QObject::connect(formatComboBox, &QComboBox::currentTextChanged, this, &SeerStackDumpBrowserWidget::handleFormatComboBox); QObject::connect(visualizerToolButton, &QToolButton::clicked, this, &SeerStackDumpBrowserWidget::handleVisualizerToolButton); QObject::connect(preferencesToolButton, &QToolButton::clicked, this, &SeerStackDumpBrowserWidget::handlePreferencesToolButton); + QObject::connect(stackTableWidget, &QTableWidget::cellDoubleClicked, this, &SeerStackDumpBrowserWidget::handleCellDoubleClicked); setStackPointerExpression("$sp"); - setBytesBeforeSP(32); - setBytesAfterSP(32); + setBytesBeforeSP(16); + setBytesAfterSP(16); setAsciiBytes(8); // Restore settings. @@ -56,7 +58,7 @@ QString SeerStackDumpBrowserWidget::stackPointerExpression () const { } void SeerStackDumpBrowserWidget::setBytesBeforeSP (int nbytes) { - _bytesBeforeSP = nbytes; + _bytesBeforeSP = ceil(nbytes / 8.0) * 8; // Round to 8. } int SeerStackDumpBrowserWidget::bytesBeforeSP () const { @@ -64,7 +66,7 @@ int SeerStackDumpBrowserWidget::bytesBeforeSP () const { } void SeerStackDumpBrowserWidget::setBytesAfterSP (int nbytes) { - _bytesAfterSP = nbytes; + _bytesAfterSP = ceil(nbytes / 8.0) * 8; // Round to 8. } int SeerStackDumpBrowserWidget::bytesAfterSP () const { @@ -111,7 +113,7 @@ void SeerStackDumpBrowserWidget::handleText (const QString& text) { addressLineEdit->setText(value_text); - emit refreshStackDump(_dumpExpressionId, value_text, 0, 64); + emit refreshStackDump(_dumpExpressionId, value_text, -bytesBeforeSP(), bytesBeforeSP()+bytesAfterSP()+2); }else if (text.contains(QRegularExpression("^([0-9]+)\\^done,memory="))) { @@ -198,6 +200,25 @@ void SeerStackDumpBrowserWidget::handlePreferencesToolButton () { refresh(); } +void SeerStackDumpBrowserWidget::handleCellDoubleClicked (int row, int col) { + + Q_UNUSED(col); + + QTableWidgetItem* item = stackTableWidget->item(row, 0); + + if (item == 0) { + return; + } + + QString address = item->text(); + + if (address.mid(0,2) != "0x") { + address.insert(0,"0x"); + } + + emit addMemoryVisualize(address); +} + void SeerStackDumpBrowserWidget::refresh () { // Don't do any work if the widget is hidden. @@ -253,6 +274,8 @@ void SeerStackDumpBrowserWidget::_populateTable (QString address, QString conten stackTableWidget->clearContents(); stackTableWidget->setRowCount(nrows); + int spRow = -1; + // Fill in the address column. for (int i=0,r=0; i < contents.length()/2; i+=2,pos64+=2,r++) { QString str = QString::number(pos64, 16); @@ -261,6 +284,11 @@ void SeerStackDumpBrowserWidget::_populateTable (QString address, QString conten item->setText(str); item->setFont(fixedFont); + if (addressLineEdit->text().contains(str)) { + item->setBackground(QBrush(QColor(Qt::lightGray))); + spRow = r; + } + stackTableWidget->setItem(r,0,item); } @@ -283,6 +311,10 @@ void SeerStackDumpBrowserWidget::_populateTable (QString address, QString conten item->setText(str); item->setFont(fixedFont); + if (r == spRow) { + item->setBackground(QBrush(QColor(Qt::lightGray))); + } + stackTableWidget->setItem(r,1,item); } @@ -307,6 +339,10 @@ void SeerStackDumpBrowserWidget::_populateTable (QString address, QString conten item->setText(str); item->setFont(fixedFont); + if (r == spRow) { + item->setBackground(QBrush(QColor(Qt::lightGray))); + } + stackTableWidget->setItem(r,2,item); } @@ -331,6 +367,10 @@ void SeerStackDumpBrowserWidget::_populateTable (QString address, QString conten item->setText(str); item->setFont(fixedFont); + if (r == spRow) { + item->setBackground(QBrush(QColor(Qt::lightGray))); + } + stackTableWidget->setItem(r,3,item); } @@ -343,6 +383,10 @@ void SeerStackDumpBrowserWidget::_populateTable (QString address, QString conten item->setText(str); item->setFont(fixedFont); + if (r == spRow) { + item->setBackground(QBrush(QColor(Qt::lightGray))); + } + stackTableWidget->setItem(r,4,item); } } diff --git a/src/SeerStackDumpBrowserWidget.h b/src/SeerStackDumpBrowserWidget.h index 91e3afb..d18d990 100644 --- a/src/SeerStackDumpBrowserWidget.h +++ b/src/SeerStackDumpBrowserWidget.h @@ -33,6 +33,7 @@ class SeerStackDumpBrowserWidget : public QWidget, protected Ui::SeerStackDumpBr void handleFormatComboBox (const QString& text); void handleVisualizerToolButton (); void handlePreferencesToolButton (); + void handleCellDoubleClicked (int row, int col); signals: void refreshStackPointer (int id, QString expression); diff --git a/src/SeerStackDumpSettingsDialog.cpp b/src/SeerStackDumpSettingsDialog.cpp index 897ece9..1fe4bac 100644 --- a/src/SeerStackDumpSettingsDialog.cpp +++ b/src/SeerStackDumpSettingsDialog.cpp @@ -15,8 +15,8 @@ SeerStackDumpSettingsDialog::SeerStackDumpSettingsDialog (QWidget* parent) : QDi // Setup the widgets setStackPointerExpression("$sp"); - setBytesBeforeSP(0); - setBytesAfterSP(32); + setBytesBeforeSP(16); + setBytesAfterSP(16); setAsciiBytes(8); // Connect things. diff --git a/src/SeerStackDumpSettingsDialog.ui b/src/SeerStackDumpSettingsDialog.ui index 694b43a..bda39ef 100644 --- a/src/SeerStackDumpSettingsDialog.ui +++ b/src/SeerStackDumpSettingsDialog.ui @@ -67,6 +67,9 @@ 8 + + 16 + @@ -101,7 +104,7 @@ 8 - 32 + 16 @@ -164,7 +167,9 @@ hr { height: 1px; border-width: 0; } li.unchecked::marker { content: "\2610"; } li.checked::marker { content: "\2612"; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The stack pointer (SP) points to where in the stack memory the program is currently at. The settings here control how the memory around the SP is displayed.<br /><br />GDB has the virtual variable called &quot;$sp&quot;, which contains the SP address. It is typical to use this as the SP expression. Some might prefer &quot;$ss*16+$sp&quot;, which is for X86 real mode. Either way, enter a gdb expression that results in an address. In most cases, $sp is enough.<br /><br />Seer can show N bytes before and N bytes after the SP, thus forming a window of bytes. N is rounded up to the next count of 8.<br /><br />Also, Seer will attempt to show the bytes as Ascii characters. The number of Ascii characters to show can be set.</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The stack pointer (SP) points to where in the stack memory the program is currently at. The settings here control how the memory around the SP is displayed.<br /><br />GDB has the virtual variable called &quot;$sp&quot;, which contains the SP address. It is typical to use this as the SP expression. Some might prefer &quot;$ss*16+$sp&quot;, which is for X86 real mode. Either way, enter a gdb expression that results in an address. In most cases, $sp is enough.<br /><br />Seer can show N bytes before and N bytes after the SP, thus forming a window of bytes. N is rounded up to the next count of 8.<br /><br />The bytes are shown as 2, 4, and 8 byte version of: hex, octal, int, uint, and float values.</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Also, Seer will attempt to show the bytes as Ascii characters. The number of Ascii characters to show can be set.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Double clicking on a row will bring up a separate Memory Visualizer for that address.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>