From 0437dd1b38acbab44d3c372539a54719c72d3471 Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 20 Sep 2025 12:31:41 -0500 Subject: [PATCH 1/5] Seer now saves the parameters from the DebugDialog so it can be used for the next session. --- src/SeerDebugDialog.cpp | 364 +++++++++++++++++--------- src/SeerDebugDialog.h | 12 + src/SeerDebugDialog.ui | 7 +- src/SeerMainWindow.cpp | 9 +- tests/helloworld/project.seer | 24 ++ tests/helloworld/project_connect.seer | 18 ++ 6 files changed, 301 insertions(+), 133 deletions(-) create mode 100644 tests/helloworld/project.seer create mode 100644 tests/helloworld/project_connect.seer diff --git a/src/SeerDebugDialog.cpp b/src/SeerDebugDialog.cpp index 5585c67..a046021 100644 --- a/src/SeerDebugDialog.cpp +++ b/src/SeerDebugDialog.cpp @@ -26,23 +26,10 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) { setupUi(this); buttonBox->button(QDialogButtonBox::Ok)->setText("Launch"); + buttonBox->button(QDialogButtonBox::Reset)->setText("Clear"); // Setup the widgets - setExecutableName(""); - setExecutableSymbolName(""); - setExecutableArguments(""); - setBreakpointsFilename(""); - setExecutableWorkingDirectory(QDir::currentPath()); - setBreakpointMode("none"); - setBreakpointFunctionName(""); - setShowAssemblyTab(false); - setRandomizeStartAddress(false); - setNonStopMode(false); - setAttachPid(0); - setConnectHostPort(""); - setRRTraceDirectory(""); - setCoreFilename(""); - setProjectFilename(""); + reset(); // Create editor options bar. QToolButton* loadProjectToolButton = new QToolButton(runModeTabWidget); @@ -84,17 +71,52 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) { QObject::connect(helpRRToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpRRToolButtonClicked); QObject::connect(helpCorefileToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpCorefileToolButtonClicked); QObject::connect(runModeTabWidget, &QTabWidget::currentChanged, this, &SeerDebugDialog::handleRunModeChanged); + QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &SeerDebugDialog::handleLaunchButtonClicked); + QObject::connect(buttonBox, &QDialogButtonBox::clicked, this, &SeerDebugDialog::handleResetButtonClicked); + // Set initial run mode. handleRunModeChanged(0); // Restore window settings. readSettings(); + + // Read default project settings, if any. + loadDefaultProjectSettings(); } SeerDebugDialog::~SeerDebugDialog () { } +void SeerDebugDialog::reset () { + + // At least retain the launch mode. + QString launchmode = launchMode(); + + // Reset everything else. + setExecutableName(""); + setExecutableSymbolName(""); + setExecutableWorkingDirectory(""); + setExecutableArguments(""); + setBreakpointsFilename(""); + setBreakpointFunctionName(""); + setBreakpointSourceName(""); + setBreakpointMode("inmain"); + setShowAssemblyTab(false); + setRandomizeStartAddress(false); + setNonStopMode(false); + setPreGdbCommands(QStringList()); + setPostGdbCommands(QStringList()); + setAttachPid(0); + setConnectHostPort(""); + setConnectRemoteTargetType("remote"); + setConnectGdbserverDebug(false); + setRRTraceDirectory(""); + setCoreFilename(""); + setLaunchMode(launchmode); + setProjectFilename(""); +} + void SeerDebugDialog::setExecutableName (const QString& executableName) { executableNameLineEdit->setText(executableName); } @@ -265,7 +287,7 @@ QString SeerDebugDialog::coreFilename () const { void SeerDebugDialog::setAttachPid (int pid) { if (pid < 1) { - attachProgramPidLineEdit->clear(); + attachProgramPidLineEdit->setText(""); }else{ attachProgramPidLineEdit->setText(QString::number(pid)); } @@ -341,11 +363,15 @@ void SeerDebugDialog::setLaunchMode (const QString& mode) { runModeTabWidget->setCurrentIndex(0); - setBreakpointMode("none"); + setBreakpointMode("inmain"); }else{ qWarning() << "Unknown launch mode of:" << mode; + + runModeTabWidget->setCurrentIndex(0); + + setBreakpointMode("inmain"); } } @@ -485,6 +511,7 @@ void SeerDebugDialog::handleLoadProjectToolButton () { void SeerDebugDialog::loadProject (const QString& filename, bool notify) { + // Look for the mainwindow to place possible QMessageBox on. QWidget* p = this; if (isHidden() == true) { @@ -508,6 +535,145 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) { // Populate the JSON document from the project file. QJsonDocument jsonDoc = QJsonDocument::fromJson(loadFile.readAll()); + + bool f = loadJsonDoc(jsonDoc, filename); + if (f == false) { + return; + } + + if (notify) { + QMessageBox::information(p, "Success", QString("Loaded the Seer project file '%1'.").arg(filename)); + } +} + +QJsonDocument SeerDebugDialog::makeJsonDoc() const { + + // Build the JSON document. + QJsonDocument jsonDoc; + QJsonObject rootJson; + QJsonObject seerProjectJson; + QJsonArray preConnectCommands; + QJsonArray postConnectCommands; + + // Save pre/post gdb commands. + QStringList preCommands = preGdbCommands(); + QStringList postCommands = postGdbCommands(); + + for (const auto& i : preCommands) { + preConnectCommands.push_back(QJsonValue(i)); + } + + for (const auto& i : postCommands) { + postConnectCommands.push_back(QJsonValue(i)); + } + + seerProjectJson["executable"] = QJsonValue(executableNameLineEdit->text()); + seerProjectJson["symbolfile"] = QJsonValue(executableSymbolNameLineEdit->text()); + seerProjectJson["workingdirectory"] = QJsonValue(executableWorkingDirectoryLineEdit->text()); + seerProjectJson["pregdbcommands"] = preConnectCommands; + seerProjectJson["postgdbcommands"] = postConnectCommands; + + // Save RUN project. + if (launchMode() == "run") { + + QJsonObject modeJson; + + modeJson["arguments"] = runProgramArgumentsLineEdit->text(); + modeJson["breakpointsfile"] = loadBreakpointsFilenameLineEdit->text(); + modeJson["nobreak"] = noBreakpointRadioButton->isChecked(); + modeJson["breakinmain"] = breakpointInMainRadioButton->isChecked(); + modeJson["breakinfunction"] = breakpointInFunctionRadioButton->isChecked(); + modeJson["breakinfunctionname"] = breakpointInFunctionLineEdit->text(); + modeJson["showassemblytab"] = showAsseblyTabCheckBox->isChecked(); + modeJson["nonstopmode"] = nonStopModeCheckBox->isChecked(); + modeJson["randomizestartaddress"] = randomizeStartAddressCheckBox->isChecked(); + + seerProjectJson["runmode"] = modeJson; + } + + // Save START project. + if (launchMode() == "start") { + + QJsonObject modeJson; + + modeJson["arguments"] = runProgramArgumentsLineEdit->text(); + modeJson["breakpointsfile"] = loadBreakpointsFilenameLineEdit->text(); + modeJson["nobreak"] = noBreakpointRadioButton->isChecked(); + modeJson["breakinmain"] = breakpointInMainRadioButton->isChecked(); + modeJson["breakinfunction"] = breakpointInFunctionRadioButton->isChecked(); + modeJson["breakinfunctionname"] = breakpointInFunctionLineEdit->text(); + modeJson["showassemblytab"] = showAsseblyTabCheckBox->isChecked(); + modeJson["nonstopmode"] = nonStopModeCheckBox->isChecked(); + modeJson["randomizestartaddress"] = randomizeStartAddressCheckBox->isChecked(); + + seerProjectJson["startmode"] = modeJson; + } + + // Save ATTACH project. + if (launchMode() == "attach") { + + QJsonObject modeJson; + + modeJson["pid"] = attachProgramPidLineEdit->text(); + + seerProjectJson["attachmode"] = modeJson; + } + + // Save CONNECT project. + if (launchMode() == "connect") { + + QJsonObject modeJson; + + modeJson["gdbserver"] = connectProgramHostPortLineEdit->text(); + modeJson["targettype"] = connectRemoteTargetTypeCombo->currentText(); + modeJson["gdbserverdebug"] = connectGdbserverDebugCheckBox->isChecked(); + + seerProjectJson["connectmode"] = modeJson; + } + + // Save RR project. + if (launchMode() == "rr") { + + QJsonObject modeJson; + + modeJson["tracedirectory"] = rrTraceDirectoryLineEdit->text(); + modeJson["breakpointsfile"] = rrLoadBreakpointsFilenameLineEdit->text(); + + seerProjectJson["rrmode"] = modeJson; + } + + // Save COREFILE project. + if (launchMode() == "corefile") { + + QJsonObject modeJson; + + modeJson["corefile"] = loadCoreFilenameLineEdit->text(); + + seerProjectJson["corefilemode"] = modeJson; + } + + rootJson["seerproject"] = seerProjectJson; + + jsonDoc.setObject(rootJson); + + return jsonDoc; +} + +bool SeerDebugDialog::loadJsonDoc (const QJsonDocument& jsonDoc, const QString& filename) { + + // Look for the mainwindow to place possible QMessageBox on. + QWidget* p = this; + + if (isHidden() == true) { + + foreach (QWidget* w, qApp->topLevelWidgets()) { + if (QMainWindow* mainWin = qobject_cast(w)) { + p = mainWin; + break; + } + } + } + QJsonObject rootJson; QJsonObject seerProjectJson; QJsonObject runModeJson; @@ -521,7 +687,7 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) { if (jsonDoc.isObject() == false) { QMessageBox::critical(p, "Error", QString("'%1' is not a Seer project file (bad Json format).").arg(filename)); - return; + return false; } rootJson = jsonDoc.object(); @@ -537,7 +703,7 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) { if (seerProjectJson.isEmpty() == true) { QMessageBox::critical(p, "Error", QString("'%1' is not a Seer project file (missing 'seerproject' section).").arg(filename)); - return; + return false; } // Load executable/symbol/working directory. @@ -660,9 +826,7 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) { setLaunchMode("corefile"); } - if (notify) { - QMessageBox::information(p, "Success", QString("Loaded the Seer project file '%1'.").arg(filename)); - } + return true; } void SeerDebugDialog::handleSaveProjectToolButton () { @@ -674,113 +838,8 @@ void SeerDebugDialog::handleSaveProjectToolButton () { return; } - // Build the JSON document. - QJsonDocument jsonDoc; - QJsonObject rootJson; - QJsonObject seerProjectJson; - QJsonArray preConnectCommands; - QJsonArray postConnectCommands; - - // Save pre/post gdb commands. - QStringList preCommands = preGdbCommands(); - QStringList postCommands = postGdbCommands(); - - for (const auto& i : preCommands) { - preConnectCommands.push_back(QJsonValue(i)); - } - - for (const auto& i : postCommands) { - postConnectCommands.push_back(QJsonValue(i)); - } - - seerProjectJson["executable"] = QJsonValue(executableNameLineEdit->text()); - seerProjectJson["symbolfile"] = QJsonValue(executableSymbolNameLineEdit->text()); - seerProjectJson["workingdirectory"] = QJsonValue(executableWorkingDirectoryLineEdit->text()); - seerProjectJson["pregdbcommands"] = preConnectCommands; - seerProjectJson["postgdbcommands"] = postConnectCommands; - - // Save RUN project. - if (launchMode() == "run") { - - QJsonObject modeJson; - - modeJson["arguments"] = runProgramArgumentsLineEdit->text(); - modeJson["breakpointsfile"] = loadBreakpointsFilenameLineEdit->text(); - modeJson["nobreak"] = noBreakpointRadioButton->isChecked(); - modeJson["breakinmain"] = breakpointInMainRadioButton->isChecked(); - modeJson["breakinfunction"] = breakpointInFunctionRadioButton->isChecked(); - modeJson["breakinfunctionname"] = breakpointInFunctionLineEdit->text(); - modeJson["showassemblytab"] = showAsseblyTabCheckBox->isChecked(); - modeJson["nonstopmode"] = nonStopModeCheckBox->isChecked(); - modeJson["randomizestartaddress"] = randomizeStartAddressCheckBox->isChecked(); - - seerProjectJson["runmode"] = modeJson; - } - - // Save START project. - if (launchMode() == "start") { - - QJsonObject modeJson; - - modeJson["arguments"] = runProgramArgumentsLineEdit->text(); - modeJson["breakpointsfile"] = loadBreakpointsFilenameLineEdit->text(); - modeJson["nobreak"] = noBreakpointRadioButton->isChecked(); - modeJson["breakinmain"] = breakpointInMainRadioButton->isChecked(); - modeJson["breakinfunction"] = breakpointInFunctionRadioButton->isChecked(); - modeJson["breakinfunctionname"] = breakpointInFunctionLineEdit->text(); - modeJson["showassemblytab"] = showAsseblyTabCheckBox->isChecked(); - modeJson["nonstopmode"] = nonStopModeCheckBox->isChecked(); - modeJson["randomizestartaddress"] = randomizeStartAddressCheckBox->isChecked(); - - seerProjectJson["startmode"] = modeJson; - } - - // Save ATTACH project. - if (launchMode() == "attach") { - - QJsonObject modeJson; - - modeJson["pid"] = attachProgramPidLineEdit->text(); - - seerProjectJson["attachmode"] = modeJson; - } - - // Save CONNECT project. - if (launchMode() == "connect") { - - QJsonObject modeJson; - - modeJson["gdbserver"] = connectProgramHostPortLineEdit->text(); - modeJson["targettype"] = connectRemoteTargetTypeCombo->currentText(); - modeJson["gdbserverdebug"] = connectGdbserverDebugCheckBox->isChecked(); - - seerProjectJson["connectmode"] = modeJson; - } - - // Save RR project. - if (launchMode() == "rr") { - - QJsonObject modeJson; - - modeJson["tracedirectory"] = rrTraceDirectoryLineEdit->text(); - modeJson["breakpointsfile"] = rrLoadBreakpointsFilenameLineEdit->text(); - - seerProjectJson["rrmode"] = modeJson; - } - - // Save COREFILE project. - if (launchMode() == "corefile") { - - QJsonObject modeJson; - - modeJson["corefile"] = loadCoreFilenameLineEdit->text(); - - seerProjectJson["corefilemode"] = modeJson; - } - - rootJson["seerproject"] = seerProjectJson; - - jsonDoc.setObject(rootJson); + // Make the json document for the debug dialog settings. + QJsonDocument jsonDoc = makeJsonDoc(); // Write the JSON document to the project file. QFile saveFile(fname); @@ -870,6 +929,26 @@ void SeerDebugDialog::handleRunModeChanged (int id) { } } +void SeerDebugDialog::handleLaunchButtonClicked () { + + QJsonDocument document = makeJsonDoc(); + + writeDefaultProjectSettings(document); +} + +void SeerDebugDialog::handleResetButtonClicked (QAbstractButton* button) { + + // Was the Reset button clicked? + QAbstractButton* resetButton = buttonBox->button(QDialogButtonBox::Reset); + + if (button != resetButton) { + return; + } + + // Reset all parameters. + reset(); +} + void SeerDebugDialog::handleHelpModeToolButtonClicked () { SeerHelpPageDialog* help = new SeerHelpPageDialog(this); @@ -924,7 +1003,7 @@ void SeerDebugDialog::writeSettings() { settings.beginGroup("debugdialog"); { settings.setValue("size", size()); - }settings.endGroup(); + } settings.endGroup(); } void SeerDebugDialog::readSettings() { @@ -936,6 +1015,31 @@ void SeerDebugDialog::readSettings() { } settings.endGroup(); } +void SeerDebugDialog::writeDefaultProjectSettings (const QJsonDocument& document) { + + QSettings settings; + + settings.beginGroup("debugdialog"); { + settings.setValue("defaultproject", document.toJson(QJsonDocument::Compact)); + } settings.endGroup(); +} + +void SeerDebugDialog::loadDefaultProjectSettings () { + + QSettings settings; + + settings.beginGroup("debugdialog"); { + + QVariant variantData = settings.value("defaultproject"); + + if (variantData.isValid()) { + QJsonDocument jsonDoc = QJsonDocument::fromJson(variantData.toByteArray()); + loadJsonDoc(jsonDoc, "defaultproject"); + } + + } settings.endGroup(); +} + void SeerDebugDialog::resizeEvent (QResizeEvent* event) { // Write window settings. diff --git a/src/SeerDebugDialog.h b/src/SeerDebugDialog.h index 7b25011..956a2af 100644 --- a/src/SeerDebugDialog.h +++ b/src/SeerDebugDialog.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "ui_SeerDebugDialog.h" @@ -19,6 +20,9 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { explicit SeerDebugDialog (QWidget* parent = 0); ~SeerDebugDialog (); + // Reset all + void reset (); + // For any run mode. void setExecutableName (const QString& executableName); QString executableName () const; @@ -81,6 +85,11 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { void setProjectFilename (const QString& filename); QString projectFilename () const; void loadProject (const QString& filename, bool notify); + void loadDefaultProjectSettings (); + + // Make a json document of the current debug dialog settings. + QJsonDocument makeJsonDoc () const; + bool loadJsonDoc (const QJsonDocument& jsonDoc, const QString& filename); protected slots: void handleExecutableNameToolButton (); @@ -94,6 +103,8 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { void handleLoadProjectToolButton (); void handleSaveProjectToolButton (); void handleRunModeChanged (int id); + void handleLaunchButtonClicked (); + void handleResetButtonClicked (QAbstractButton* button); private slots: void handleHelpModeToolButtonClicked (); @@ -106,6 +117,7 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { protected: void writeSettings (); void readSettings (); + void writeDefaultProjectSettings (const QJsonDocument& document); void resizeEvent (QResizeEvent* event); private: diff --git a/src/SeerDebugDialog.ui b/src/SeerDebugDialog.ui index 5a7b836..f075ad2 100644 --- a/src/SeerDebugDialog.ui +++ b/src/SeerDebugDialog.ui @@ -227,7 +227,7 @@ - 2 + 4 @@ -960,6 +960,9 @@ The path and name of a core file. + + The path and name of the core file. + true @@ -1007,7 +1010,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset diff --git a/src/SeerMainWindow.cpp b/src/SeerMainWindow.cpp index e6e3f57..cf2f69a 100644 --- a/src/SeerMainWindow.cpp +++ b/src/SeerMainWindow.cpp @@ -568,7 +568,14 @@ void SeerMainWindow::handleFileDebug () { dlg.setCoreFilename(executableCoreFilename()); dlg.setPreGdbCommands(executablePreGdbCommands()); dlg.setPostGdbCommands(executablePostGdbCommands()); - dlg.setProjectFilename(projectFilename()); + + // If there's a project, use it. + if (projectFilename() != "") { + dlg.setProjectFilename(projectFilename()); + // Otherwise use the default project, if there is one. + }else{ + dlg.loadDefaultProjectSettings(); + } setProjectFilename(""); // Clear project name here. No need to have it anymore. diff --git a/tests/helloworld/project.seer b/tests/helloworld/project.seer new file mode 100644 index 0000000..216c457 --- /dev/null +++ b/tests/helloworld/project.seer @@ -0,0 +1,24 @@ +{ + "seerproject": { + "executable": "/nas/erniep/Development/seer/tests/helloworld/helloworld", + "postgdbcommands": [ + "" + ], + "pregdbcommands": [ + "" + ], + "startmode": { + "arguments": "one two three", + "breakinfunction": false, + "breakinfunctionname": "", + "breakinmain": true, + "breakpointsfile": "", + "nobreak": false, + "nonstopmode": false, + "randomizestartaddress": false, + "showassemblytab": false + }, + "symbolfile": "", + "workingdirectory": "/nas/erniep/Development/seer/tests/helloworld" + } +} diff --git a/tests/helloworld/project_connect.seer b/tests/helloworld/project_connect.seer new file mode 100644 index 0000000..3e6bc73 --- /dev/null +++ b/tests/helloworld/project_connect.seer @@ -0,0 +1,18 @@ +{ + "seerproject": { + "connectmode": { + "gdbserver": ":1234", + "gdbserverdebug": false, + "targettype": "extended-remote" + }, + "executable": "/nas/erniep/Development/seer/tests/helloworld/helloworld", + "postgdbcommands": [ + "" + ], + "pregdbcommands": [ + "" + ], + "symbolfile": "", + "workingdirectory": "/nas/erniep/Development/seer/tests/helloworld" + } +} From 37da2ba08ae584763d61000c6a5a02c752993fc3 Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 20 Sep 2025 15:56:10 -0500 Subject: [PATCH 2/5] Fix copyright. --- src/seergdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seergdb.cpp b/src/seergdb.cpp index f5a6002..bc95cec 100644 --- a/src/seergdb.cpp +++ b/src/seergdb.cpp @@ -57,7 +57,7 @@ int main (int argc, char* argv[]) { QCoreApplication::setApplicationName("seergdb"); QCoreApplication::setOrganizationName("seergdb"); - QCoreApplication::setApplicationVersion(Seer::version() + " - Ernie Pasveer (c)2021 - 2024"); + QCoreApplication::setApplicationVersion(Seer::version() + " - Ernie Pasveer (c)2021 - 2025"); // // Parse arguments. From 286ad666897cf23abdcd65edc811009c20c311b8 Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 20 Sep 2025 17:55:32 -0500 Subject: [PATCH 3/5] If the RR trace directory isn't given, try a couple standard places. --- src/SeerDebugDialog.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/SeerDebugDialog.cpp b/src/SeerDebugDialog.cpp index a046021..ab2486c 100644 --- a/src/SeerDebugDialog.cpp +++ b/src/SeerDebugDialog.cpp @@ -7,6 +7,7 @@ #include "SeerDirectoryFilterProxyModel.h" #include "SeerSlashProcDialog.h" #include "SeerHelpPageDialog.h" +#include "SeerUtl.h" #include "QHContainerWidget.h" #include #include @@ -916,6 +917,30 @@ void SeerDebugDialog::handleRunModeChanged (int id) { executableSymbolNameToolButton->setEnabled(true); preCommandsPlainTextEdit->setPlaceholderText("gdb commands before \"RR trace-directory load\""); postCommandsPlainTextEdit->setPlaceholderText("gdb commands after \"RR trace-directory load\""); + + // Set default if we can. Otherwise, leave it blank. + // + if (rrTraceDirectoryLineEdit->text() == "") { + QStringList searchPaths = { + "$_RR_TRACE_DIR/latest-trace", + "$XDG_DATA_HOME/rr/latest-trace", + "$HOME/.local/share/rr/latest-trace" + }; + + QString defaultPath = ""; + bool f; + + for (const auto& path : searchPaths) { + defaultPath = Seer::expandEnv(path, &f); + if (f == false) { + continue; + } + if (QFile::exists(defaultPath)) { + setRRTraceDirectory(defaultPath); + break; + } + } + } } // ID == 4 COREFILE From e64f254f7033ff03aece6c9cb979b8d845777ccf Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 20 Sep 2025 17:57:39 -0500 Subject: [PATCH 4/5] Update CHANGELOG. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00eef6d..ca5d52c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ * Add support for remaining Catchpoint types. * Add a Matrix Visualizer for viewing 2D arrays. * Add breakpoints from the Function tab. +* RR: When using the Debug dialog, check a couple standard locations for + the RR trace directory. ## [2.5] - 2024-12-24 * Console now supports a subset of ANSI color codes. From 19aa69e11f185eb1b12c20a2cfa549e762579e19 Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 20 Sep 2025 17:58:59 -0500 Subject: [PATCH 5/5] Update CHANGELOG. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca5d52c..d50dc5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ * Add support for remaining Catchpoint types. * Add a Matrix Visualizer for viewing 2D arrays. * Add breakpoints from the Function tab. +* When using the Debug dialog, save the debug settings so they can be fast loaded + the next time the Debug dialog is used. Kind of a default project. * RR: When using the Debug dialog, check a couple standard locations for the RR trace directory.