diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec35a74..7d2dfad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,6 +53,7 @@ set(HEADER_FILES SeerConsoleWidget.h SeerConfigDialog.h SeerGdbConfigPage.h + SeerRRConfigPage.h SeerEditorConfigPage.h SeerSourceConfigPage.h SeerAssemblyConfigPage.h @@ -143,6 +144,7 @@ set(SOURCE_FILES SeerConsoleWidget.cpp SeerConfigDialog.cpp SeerGdbConfigPage.cpp + SeerRRConfigPage.cpp SeerEditorConfigPage.cpp SeerSourceConfigPage.cpp SeerAssemblyConfigPage.cpp diff --git a/src/SeerConfigDialog.cpp b/src/SeerConfigDialog.cpp index 385660c..7a29576 100644 --- a/src/SeerConfigDialog.cpp +++ b/src/SeerConfigDialog.cpp @@ -40,22 +40,30 @@ SeerConfigDialog::SeerConfigDialog(QWidget* parent) : QDialog(parent) { } // Create pages. + _seerConfigPage = new SeerSeerConfigPage; _gdbConfigPage = new SeerGdbConfigPage; _editorConfigPage = new SeerEditorConfigPage; _sourceConfigPage = new SeerSourceConfigPage; _assemblyConfigPage = new SeerAssemblyConfigPage; _keysConfigPage = new SeerKeysConfigPage; - _seerConfigPage = new SeerSeerConfigPage; + _rrConfigPage = new SeerRRConfigPage; // Add the pages to the stacked widget. + pagesStackedWidget->addWidget(_seerConfigPage); pagesStackedWidget->addWidget(_gdbConfigPage); pagesStackedWidget->addWidget(_editorConfigPage); pagesStackedWidget->addWidget(_sourceConfigPage); pagesStackedWidget->addWidget(_assemblyConfigPage); pagesStackedWidget->addWidget(_keysConfigPage); - pagesStackedWidget->addWidget(_seerConfigPage); + pagesStackedWidget->addWidget(_rrConfigPage); // Create icons. + QListWidgetItem* configSeerButton = new QListWidgetItem(contentsListWidget); + configSeerButton->setIcon(QIcon(":/seer/resources/seergdb_128x128.png")); + configSeerButton->setText(tr("Seer")); + configSeerButton->setTextAlignment(Qt::AlignHCenter); + configSeerButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + QListWidgetItem* configGdbButton = new QListWidgetItem(contentsListWidget); configGdbButton->setIcon(QIcon(":/seer/resources/icons-icons/gdb.png")); configGdbButton->setText(tr("GDB")); @@ -86,11 +94,11 @@ SeerConfigDialog::SeerConfigDialog(QWidget* parent) : QDialog(parent) { configKeysButton->setTextAlignment(Qt::AlignHCenter); configKeysButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - QListWidgetItem* configSeerButton = new QListWidgetItem(contentsListWidget); - configSeerButton->setIcon(QIcon(":/seer/resources/seergdb_128x128.png")); - configSeerButton->setText(tr("Seer")); - configSeerButton->setTextAlignment(Qt::AlignHCenter); - configSeerButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + QListWidgetItem* configRRButton = new QListWidgetItem(contentsListWidget); + configRRButton->setIcon(QIcon(":/seer/resources/rr_256x256.png")); + configRRButton->setText(tr("RR")); + configRRButton->setTextAlignment(Qt::AlignHCenter); + configRRButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); // Connect things. connect(contentsListWidget, &QListWidget::currentItemChanged, this, &SeerConfigDialog::handleChangePage); @@ -103,6 +111,55 @@ SeerConfigDialog::SeerConfigDialog(QWidget* parent) : QDialog(parent) { SeerConfigDialog::~SeerConfigDialog() { } +void SeerConfigDialog::setSeerConsoleMode (const QString& mode) { + + _seerConfigPage->setConsoleMode(mode); +} + +QString SeerConfigDialog::seerConsoleMode () const { + + return _seerConfigPage->consoleMode(); +} + +void SeerConfigDialog::setSeerConsoleScrollLines (int count) { + + _seerConfigPage->setConsoleScrollLines(count); +} + +int SeerConfigDialog::seerConsoleScrollLines () const { + + return _seerConfigPage->consoleScrollLines(); +} +void SeerConfigDialog::setSeerRememberWindowSizes (bool flag) { + + _seerConfigPage->setRememberWindowSizes(flag); +} + +bool SeerConfigDialog::seerRememberWindowSizes () const { + + return _seerConfigPage->rememberWindowSizes(); +} + +void SeerConfigDialog::setSeerRememberManualCommandCount (int count) { + + _seerConfigPage->setRememberManualCommandCount(count); +} + +int SeerConfigDialog::seerRememberManualCommandCount () const { + + return _seerConfigPage->rememberManualCommandCount(); +} + +void SeerConfigDialog::setSeerClearManualCommandHistory (bool flag) { + + _seerConfigPage->setClearManualCommandHistory(flag); +} + +bool SeerConfigDialog::seerClearManualCommandHistory () const { + + return _seerConfigPage->clearManualCommandHistory(); +} + void SeerConfigDialog::setGdbProgram (const QString& program) { _gdbConfigPage->setGdbProgram(program); @@ -408,53 +465,34 @@ SeerKeySettings SeerConfigDialog::keySettings () const { return _keysConfigPage->keySettings(); } -void SeerConfigDialog::setSeerConsoleMode (const QString& mode) { +void SeerConfigDialog::setRRProgram (const QString& program) { - _seerConfigPage->setConsoleMode(mode); + _rrConfigPage->setRRProgram(program); } -QString SeerConfigDialog::seerConsoleMode () const { +QString SeerConfigDialog::rrProgram () const { - return _seerConfigPage->consoleMode(); + return _rrConfigPage->rrProgram(); } -void SeerConfigDialog::setSeerConsoleScrollLines (int count) { +void SeerConfigDialog::setRRArguments (const QString& arguments) { - _seerConfigPage->setConsoleScrollLines(count); + _rrConfigPage->setRRArguments(arguments); } -int SeerConfigDialog::seerConsoleScrollLines () const { +QString SeerConfigDialog::rrArguments () const { - return _seerConfigPage->consoleScrollLines(); -} -void SeerConfigDialog::setSeerRememberWindowSizes (bool flag) { - - _seerConfigPage->setRememberWindowSizes(flag); + return _rrConfigPage->rrArguments(); } -bool SeerConfigDialog::seerRememberWindowSizes () const { +void SeerConfigDialog::setRRGdbArguments (const QString& arguments) { - return _seerConfigPage->rememberWindowSizes(); + _rrConfigPage->setGdbArguments(arguments); } -void SeerConfigDialog::setSeerRememberManualCommandCount (int count) { +QString SeerConfigDialog::rrGdbArguments () const { - _seerConfigPage->setRememberManualCommandCount(count); -} - -int SeerConfigDialog::seerRememberManualCommandCount () const { - - return _seerConfigPage->rememberManualCommandCount(); -} - -void SeerConfigDialog::setSeerClearManualCommandHistory (bool flag) { - - _seerConfigPage->setClearManualCommandHistory(flag); -} - -bool SeerConfigDialog::seerClearManualCommandHistory () const { - - return _seerConfigPage->clearManualCommandHistory(); + return _rrConfigPage->gdbArguments(); } void SeerConfigDialog::handleChangePage(QListWidgetItem* current, QListWidgetItem* previous) { @@ -506,6 +544,10 @@ void SeerConfigDialog::handleButtonClicked (QAbstractButton* button) { }else if (itemLabel == "Seer") { _seerConfigPage->reset(); + + }else if (itemLabel == "RR") { + + _rrConfigPage->reset(); } } } diff --git a/src/SeerConfigDialog.h b/src/SeerConfigDialog.h index e1a7561..2c88e1c 100644 --- a/src/SeerConfigDialog.h +++ b/src/SeerConfigDialog.h @@ -1,6 +1,7 @@ #pragma once #include "SeerGdbConfigPage.h" +#include "SeerRRConfigPage.h" #include "SeerEditorConfigPage.h" #include "SeerSourceConfigPage.h" #include "SeerAssemblyConfigPage.h" @@ -22,6 +23,22 @@ class SeerConfigDialog : public QDialog, protected Ui::SeerConfigDialogForm { explicit SeerConfigDialog (QWidget* parent = 0); ~SeerConfigDialog (); + // Seer settings. + void setSeerConsoleMode (const QString& mode); + QString seerConsoleMode () const; + + void setSeerConsoleScrollLines (int count); + int seerConsoleScrollLines () const; + + void setSeerRememberWindowSizes (bool flag); + bool seerRememberWindowSizes () const; + + void setSeerRememberManualCommandCount (int count); + int seerRememberManualCommandCount () const; + + void setSeerClearManualCommandHistory (bool flag); + bool seerClearManualCommandHistory () const; + // Gdb settings. void setGdbProgram (const QString& program); QString gdbProgram () const; @@ -118,21 +135,15 @@ class SeerConfigDialog : public QDialog, protected Ui::SeerConfigDialogForm { void setKeySettings (const SeerKeySettings& settings); SeerKeySettings keySettings () const; - // Seer settings. - void setSeerConsoleMode (const QString& mode); - QString seerConsoleMode () const; + // RR settings. + void setRRProgram (const QString& program); + QString rrProgram () const; - void setSeerConsoleScrollLines (int count); - int seerConsoleScrollLines () const; + void setRRArguments (const QString& arguments); + QString rrArguments () const; - void setSeerRememberWindowSizes (bool flag); - bool seerRememberWindowSizes () const; - - void setSeerRememberManualCommandCount (int count); - int seerRememberManualCommandCount () const; - - void setSeerClearManualCommandHistory (bool flag); - bool seerClearManualCommandHistory () const; + void setRRGdbArguments (const QString& arguments); + QString rrGdbArguments () const; public slots: void handleChangePage (QListWidgetItem* current, QListWidgetItem* previous); @@ -140,6 +151,7 @@ class SeerConfigDialog : public QDialog, protected Ui::SeerConfigDialogForm { private: SeerGdbConfigPage* _gdbConfigPage; + SeerRRConfigPage* _rrConfigPage; SeerEditorConfigPage* _editorConfigPage; SeerSourceConfigPage* _sourceConfigPage; SeerAssemblyConfigPage* _assemblyConfigPage; diff --git a/src/SeerDebugDialog.cpp b/src/SeerDebugDialog.cpp index 651f67e..1383569 100644 --- a/src/SeerDebugDialog.cpp +++ b/src/SeerDebugDialog.cpp @@ -34,7 +34,7 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) { setNonStopMode(false); setAttachPid(0); setConnectHostPort(""); - setRRHostPort(""); + setRRTraceDirectory(""); setCoreFilename(""); setProjectFilename(""); @@ -248,12 +248,12 @@ QString SeerDebugDialog::connectHostPort () const { return connectProgramHostPortLineEdit->text(); } -void SeerDebugDialog::setRRHostPort (const QString& rrHostPort) { - rrHostPortLineEdit->setText(rrHostPort); +void SeerDebugDialog::setRRTraceDirectory (const QString& rrTraceDirectory) { + rrTraceDirectoryLineEdit->setText(rrTraceDirectory); } -QString SeerDebugDialog::rrHostPort () const { - return rrHostPortLineEdit->text(); +QString SeerDebugDialog::rrTraceDirectory () const { + return rrTraceDirectoryLineEdit->text(); } void SeerDebugDialog::setLaunchMode (const QString& mode) { @@ -575,7 +575,7 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) { // Load RR project. if (rrModeJson.isEmpty() == false) { - connectProgramHostPortLineEdit->setText(rrModeJson["rrserver"].toString()); + rrTraceDirectoryLineEdit->setText(rrModeJson["rrtracedirectory"].toString()); setLaunchMode("rr"); } @@ -688,7 +688,7 @@ void SeerDebugDialog::handleSaveProjectToolButton () { QJsonObject modeJson; - modeJson["rrserver"] = rrHostPortLineEdit->text(); + modeJson["rrtracedirectory"] = rrTraceDirectoryLineEdit->text(); seerProjectJson["rrmode"] = modeJson; } diff --git a/src/SeerDebugDialog.h b/src/SeerDebugDialog.h index 01ef27b..ef58544 100644 --- a/src/SeerDebugDialog.h +++ b/src/SeerDebugDialog.h @@ -54,8 +54,8 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { QString connectHostPort () const; // Connectect to a RR server. "rr". - void setRRHostPort (const QString& rrHostPort); - QString rrHostPort () const; + void setRRTraceDirectory (const QString& rrTraceDirectory); + QString rrTraceDirectory () const; // Load a core file. "corefile". void setCoreFilename (const QString& coreFilename); diff --git a/src/SeerDebugDialog.ui b/src/SeerDebugDialog.ui index 18681a1..0d8d2b3 100644 --- a/src/SeerDebugDialog.ui +++ b/src/SeerDebugDialog.ui @@ -207,7 +207,7 @@ - 2 + 3 @@ -650,7 +650,7 @@ - Connect to a RR replay session. + Load a RR trace session. @@ -686,14 +686,14 @@ - + - RR replay session + RR trace directory - + 100 @@ -701,13 +701,13 @@ - How to access the RR session. + How to access the RR trace session. - host:port + /path/to/rr/trace/directory true diff --git a/src/SeerGdbConfigPage.ui b/src/SeerGdbConfigPage.ui index d5d9095..34ecad1 100644 --- a/src/SeerGdbConfigPage.ui +++ b/src/SeerGdbConfigPage.ui @@ -124,9 +124,6 @@ - - Show variables with gdb's 'pretty-print' system. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp index 5b100da..ac4728f 100644 --- a/src/SeerGdbWidget.cpp +++ b/src/SeerGdbWidget.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,7 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) { _executableBreakpointsFilename = ""; _executableBreakpointFunctionName = ""; _executableConnectHostPort = ""; - _executableRRHostPort = ""; + _executableRRTraceDirectory = ""; _executableCoreFilename = ""; _executablePid = 0; @@ -447,12 +448,12 @@ const QString& SeerGdbWidget::executableConnectHostPort () const { return _executableConnectHostPort; } -void SeerGdbWidget::setExecutableRRHostPort (const QString& rrHostPort) { - _executableRRHostPort = rrHostPort; +void SeerGdbWidget::setExecutableRRTraceDirectory (const QString& rrTraceDirectory) { + _executableRRTraceDirectory = rrTraceDirectory; } -const QString& SeerGdbWidget::executableRRHostPort () const { - return _executableRRHostPort; +const QString& SeerGdbWidget::executableRRTraceDirectory () const { + return _executableRRTraceDirectory; } void SeerGdbWidget::setExecutableCoreFilename (const QString& coreFilename) { @@ -511,6 +512,36 @@ QString SeerGdbWidget::gdbArguments () const { return _gdbArguments; } +void SeerGdbWidget::setRRProgram (const QString& program) { + + _gdbRRProgram = program; +} + +QString SeerGdbWidget::rrProgram () const { + + return _gdbRRProgram; +} + +void SeerGdbWidget::setRRArguments (const QString& arguments) { + + _gdbRRArguments = arguments; +} + +QString SeerGdbWidget::rrArguments () const { + + return _gdbRRArguments; +} + +void SeerGdbWidget::setRRGdbArguments (const QString& arguments) { + + _gdbRRGdbArguments = arguments; +} + +QString SeerGdbWidget::rrGdbArguments () const { + + return _gdbRRGdbArguments; +} + void SeerGdbWidget::setGdbAsyncMode (bool flag) { _gdbASyncMode = flag; @@ -1140,7 +1171,7 @@ void SeerGdbWidget::handleGdbConnectExecutable () { qCDebug(LC) << "Finishing 'gdb connect'."; } -void SeerGdbWidget::handleGdbDirectRRExecutable () { +void SeerGdbWidget::handleGdbRRExecutable () { qCDebug(LC) << "Starting 'gdb direct rr'."; @@ -1218,91 +1249,7 @@ void SeerGdbWidget::handleGdbDirectRRExecutable () { handleGdbExecutablePostCommands(); // Set window titles with name of program. - emit changeWindowTitle(QString("%1 (pid=%2)").arg(executableRRHostPort()).arg(QGuiApplication::applicationPid())); - - break; - } - - QApplication::restoreOverrideCursor(); - - qCDebug(LC) << "Finishing 'gdb rr'."; -} - -void SeerGdbWidget::handleGdbRRExecutable () { - - qCDebug(LC) << "Starting 'gdb rr'."; - - QApplication::setOverrideCursor(Qt::BusyCursor); - - while (1) { - - // Has a executable name been provided? - if (executableName() != "") { - - QMessageBox::warning(this, "Seer", - QString("The executable name can't be provided for 'rr' mode."), - QMessageBox::Ok); - break; - } - - // Delete the old gdb and console if there is a new executable - if (newExecutableFlag() == true) { - killGdb(); - disconnectConsole(); - deleteConsole(); - } - - // If gdb isn't running, start it. - if (isGdbRuning() == false) { - - bool f = startGdb(); - if (f == false) { - QMessageBox::critical(this, tr("Error"), tr("Can't start gdb.")); - break; - } - } - - // Set dprint parameters. - resetDprintf(); - - // No console for 'rr' mode. - setExecutableLaunchMode("rr"); - setGdbRecordMode("rr"); - setExecutablePid(0); - - // Connect to the remote gdbserver. - handleGdbCommand(QString("-target-select extended-remote %1").arg(executableRRHostPort())); - - // Load ithe executable, if needed. - if (newExecutableFlag() == true) { - handleGdbExecutablePreCommands(); // Run any 'pre' commands before program is loaded. - handleGdbExecutableName(); // Load the program into the gdb process. - handleGdbExecutableSources(); // Load the program source files. - handleGdbExecutableLoadBreakpoints(); // Set the program's breakpoints (if any) before running. - - setNewExecutableFlag(false); - } - - // Set or reset some things. - handleGdbExecutableWorkingDirectory(); // Set the program's working directory before running. - handleGdbAssemblyDisassemblyFlavor(); // Set the disassembly flavor to use. - handleGdbAssemblySymbolDemangling(); // Set the symbol demangling. - - if (assemblyShowAssemblyTabOnStartup()) { - editorManager()->showAssembly(); - } - - if (gdbHandleTerminatingException()) { - handleGdbCommand("-gdb-set unwind-on-terminating-exception on"); // Turn on terminating exceptions when gdb calls the program's functions. - }else{ - handleGdbCommand("-gdb-set unwind-on-terminating-exception off"); - } - - // Run any 'post' commands after program is loaded. - handleGdbExecutablePostCommands(); - - // Set window titles with name of program. - emit changeWindowTitle(QString("%1 (pid=%2)").arg(executableRRHostPort()).arg(QGuiApplication::applicationPid())); + emit changeWindowTitle(QString("%1 (pid=%2)").arg(executableRRTraceDirectory()).arg(QGuiApplication::applicationPid())); break; } @@ -2776,7 +2723,7 @@ void SeerGdbWidget::handleGdbProcessFinished (int exitCode, QProcess::ExitStatus QMessageBox::warning(this, "Seer", QString("The GDB program exited unexpectedly.\n\n") + QString("Exit code=%1 Exit status=%2").arg(exitCode).arg(exitStatus) + "\n\n" + - QString("'%1 %2'").arg(gdbProgram()).arg(gdbArguments()) + "\n\n" + + QString("'%1 %2'").arg(_gdbProcess->program()).arg(_gdbProcess->arguments().join(' ')) + "\n\n" + QString("Please restart Seer."), QMessageBox::Ok); } @@ -2789,7 +2736,7 @@ void SeerGdbWidget::handleGdbProcessErrored (QProcess::ProcessError errorStatus) if (errorStatus == QProcess::FailedToStart) { QMessageBox::warning(this, "Seer", QString("Unable to launch the GDB program.\n\n") + - QString("'%1 %2'").arg(gdbProgram()).arg(gdbArguments()) + "\n\n" + + QString("'%1 %2'").arg(_gdbProcess->program()).arg(_gdbProcess->arguments().join(' ')) + "\n\n" + QString("Error status=%1)").arg(errorStatus), QMessageBox::Ok); } @@ -3089,10 +3036,23 @@ bool SeerGdbWidget::startGdbRR () { return false; } + // Does the RR trace directory exist? + if (QFile::exists(executableRRTraceDirectory()) == false) { + QMessageBox::critical(this, "Seer", + QString("The RR trace-directory '" + executableRRTraceDirectory() + "' doesn't exist."), + QMessageBox::Ok); + return false; + } + // Set the gdb program name to use. - QString command = "/usr/local/bin/rr"; - QString arguments = "replay --interpreter=mi --tty " + _consoleWidget->ttyDeviceName(); - QStringList args = arguments.split(' ', Qt::SkipEmptyParts); + QString command = "/usr/local/bin/rr"; + QString arguments = "replay --interpreter=mi --tty " + _consoleWidget->ttyDeviceName() + " " + executableRRTraceDirectory(); + + if (rrGdbArguments() != "") { + arguments += " -- " + rrGdbArguments(); + } + + QStringList args = arguments.split(' ', Qt::SkipEmptyParts); qDebug() << "Expanded command: " << command; qDebug() << "Expanded arguments: " << arguments; diff --git a/src/SeerGdbWidget.h b/src/SeerGdbWidget.h index d5c620e..fea9780 100644 --- a/src/SeerGdbWidget.h +++ b/src/SeerGdbWidget.h @@ -53,8 +53,8 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void setExecutableConnectHostPort (const QString& connectHostPort); const QString& executableConnectHostPort () const; - void setExecutableRRHostPort (const QString& rrHostPort); - const QString& executableRRHostPort () const; + void setExecutableRRTraceDirectory (const QString& rrTraceDirectory); + const QString& executableRRTraceDirectory () const; void setExecutableCoreFilename (const QString& coreFilename); const QString& executableCoreFilename () const; @@ -174,6 +174,16 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void setSeerOutputLogEnabled (bool flag); bool isSeerOutputLogEnabled () const; + // RR settings. + void setRRProgram (const QString& program); + QString rrProgram () const; + + void setRRArguments (const QString& arguments); + QString rrArguments () const; + + void setRRGdbArguments (const QString& arguments); + QString rrGdbArguments () const; + // Editor manager. SeerEditorManagerWidget* editorManager (); const SeerEditorManagerWidget* editorManager () const; @@ -197,7 +207,6 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void handleGdbAttachExecutable (); void handleGdbConnectExecutable (); void handleGdbRRExecutable (); - void handleGdbDirectRRExecutable (); void handleGdbCoreFileExecutable (); void handleGdbShutdown (); void handleGdbRunToLine (QString fullname, int lineno); @@ -345,6 +354,9 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { QString _gdbProgram; QString _gdbArguments; + QString _gdbRRProgram; + QString _gdbRRArguments; + QString _gdbRRGdbArguments; bool _gdbASyncMode; bool _gdbNonStopMode; bool _gdbHandleTerminatingException; @@ -370,7 +382,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { QString _executableBreakpointFunctionName; int _executablePid; QString _executableConnectHostPort; - QString _executableRRHostPort; + QString _executableRRTraceDirectory; QString _executableCoreFilename; QString _executableLaunchMode; QString _executableBreakMode; diff --git a/src/SeerMainWindow.cpp b/src/SeerMainWindow.cpp index bbf1a1d..e758223 100644 --- a/src/SeerMainWindow.cpp +++ b/src/SeerMainWindow.cpp @@ -191,15 +191,19 @@ SeerMainWindow::SeerMainWindow(QWidget* parent) : QMainWindow(parent) { handleRecordSettingsChanged(); + // + // Initialize contents. + // + // Restore window settings. readSettings(); // Restore configuration settings. readConfigSettings(); - // - // Initialize contents. - // + // Show the main window. + show(); + handleShowMessage("Welcome to Seer. The All Knowing...", 3000); } @@ -324,12 +328,12 @@ const QString& SeerMainWindow::executableConnectHostPort () const { return gdbWidget->executableConnectHostPort(); } -void SeerMainWindow::setExecutableRRHostPort (const QString& executableRRHostPort) { - gdbWidget->setExecutableRRHostPort(executableRRHostPort); +void SeerMainWindow::setExecutableRRTraceDirectory (const QString& executableRRTraceDirectory) { + gdbWidget->setExecutableRRTraceDirectory(executableRRTraceDirectory); } -const QString& SeerMainWindow::executableRRHostPort () const { - return gdbWidget->executableRRHostPort(); +const QString& SeerMainWindow::executableRRTraceDirectory () const { + return gdbWidget->executableRRTraceDirectory(); } void SeerMainWindow::setExecutableCoreFilename (const QString& executableCoreFilename) { @@ -402,8 +406,7 @@ void SeerMainWindow::launchExecutable (const QString& launchMode, const QString& actionGdbRun->setVisible(false); actionGdbStart->setVisible(false); - //gdbWidget->handleGdbRRExecutable(); - gdbWidget->handleGdbDirectRRExecutable(); + gdbWidget->handleGdbRRExecutable(); }else if (launchMode == "corefile") { @@ -461,7 +464,7 @@ void SeerMainWindow::handleFileDebug () { dlg.setNonStopMode(executableNonStopMode()); dlg.setAttachPid(executablePid()); dlg.setConnectHostPort(executableConnectHostPort()); - dlg.setRRHostPort(executableRRHostPort()); + dlg.setRRTraceDirectory(executableRRTraceDirectory()); dlg.setCoreFilename(executableCoreFilename()); dlg.setLaunchMode(executableLaunchMode()); dlg.setBreakpointMode(executableBreakMode()); @@ -495,7 +498,7 @@ void SeerMainWindow::handleFileDebug () { setExecutableNonStopMode(dlg.nonStopMode()); setExecutablePid(dlg.attachPid()); setExecutableConnectHostPort(dlg.connectHostPort()); - setExecutableRRHostPort(dlg.rrHostPort()); + setExecutableRRTraceDirectory(dlg.rrTraceDirectory()); setExecutableCoreFilename(dlg.coreFilename()); setExecutablePreGdbCommands(dlg.preGdbCommands()); setExecutablePostGdbCommands(dlg.postGdbCommands()); @@ -600,6 +603,9 @@ void SeerMainWindow::handleSettingsConfiguration () { SeerConfigDialog dlg(this); + dlg.setSeerConsoleMode(gdbWidget->consoleMode()); + dlg.setSeerConsoleScrollLines(gdbWidget->consoleScrollLines()); + dlg.setSeerRememberManualCommandCount(gdbWidget->rememberManualCommandCount()); dlg.setGdbProgram(gdbWidget->gdbProgram()); dlg.setGdbArguments(gdbWidget->gdbArguments()); dlg.setGdbAsyncMode(gdbWidget->gdbAsyncMode()); @@ -629,9 +635,6 @@ void SeerMainWindow::handleSettingsConfiguration () { dlg.setAssemblyShowSourceLines(gdbWidget->assemblyShowSourceLines()); dlg.setAssemblyRegisterFormat(gdbWidget->assemblyRegisterFormat()); dlg.setAssemblyDisassemblyMode(gdbWidget->assemblyDisassemblyMode(), gdbWidget->assemblyDisassemblyBytes()); - dlg.setSeerConsoleMode(gdbWidget->consoleMode()); - dlg.setSeerConsoleScrollLines(gdbWidget->consoleScrollLines()); - dlg.setSeerRememberManualCommandCount(gdbWidget->rememberManualCommandCount()); dlg.setKeySettings(keySettings()); int ret = dlg.exec(); @@ -641,6 +644,9 @@ void SeerMainWindow::handleSettingsConfiguration () { } // Update the GdbWidget with the new settings. + gdbWidget->setConsoleMode(dlg.seerConsoleMode()); + gdbWidget->setConsoleScrollLines(dlg.seerConsoleScrollLines()); + gdbWidget->setRememberManualCommandCount(dlg.seerRememberManualCommandCount()); gdbWidget->setGdbProgram(dlg.gdbProgram()); gdbWidget->setGdbArguments(dlg.gdbArguments()); gdbWidget->setGdbAsyncMode(dlg.gdbAsyncMode()); @@ -669,9 +675,9 @@ void SeerMainWindow::handleSettingsConfiguration () { gdbWidget->setAssemblyShowSourceLines(dlg.assemblyShowSourceLines()); gdbWidget->setAssemblyRegisterFormat(dlg.assemblyRegisterFormat()); gdbWidget->setAssemblyDisassemblyMode(dlg.assemblyDisassemblyMode(), dlg.assemblyDisassemblyBytes()); - gdbWidget->setConsoleMode(dlg.seerConsoleMode()); - gdbWidget->setConsoleScrollLines(dlg.seerConsoleScrollLines()); - gdbWidget->setRememberManualCommandCount(dlg.seerRememberManualCommandCount()); + gdbWidget->setRRProgram(dlg.rrProgram()); + gdbWidget->setRRArguments(dlg.rrArguments()); + gdbWidget->setRRGdbArguments(dlg.rrGdbArguments()); // Clear history, if we need to. bool clearManualCommandHistory = dlg.seerClearManualCommandHistory(); @@ -711,6 +717,7 @@ void SeerMainWindow::handleHelpAbout () { } void SeerMainWindow::handleRunExecutable () { + gdbWidget->handleGdbRunExecutable("none"); } @@ -1178,6 +1185,12 @@ void SeerMainWindow::writeConfigSettings () { settings.setValue("enableprettyprinting", gdbWidget->gdbEnablePrettyPrinting()); } settings.endGroup(); + settings.beginGroup("rr"); { + settings.setValue("program", gdbWidget->rrProgram()); + settings.setValue("arguments", gdbWidget->rrArguments()); + settings.setValue("gdbarguments", gdbWidget->rrGdbArguments()); + } settings.endGroup(); + settings.beginGroup("printpoints"); { settings.setValue("style", gdbWidget->dprintfStyle()); settings.setValue("function", gdbWidget->dprintfFunction()); @@ -1253,6 +1266,12 @@ void SeerMainWindow::readConfigSettings () { gdbWidget->setGdbEnablePrettyPrinting(settings.value("enableprettyprinting", true).toBool()); } settings.endGroup(); + settings.beginGroup("rr"); { + gdbWidget->setRRProgram(settings.value("program", "/usr/bin/rr").toString()); + gdbWidget->setRRArguments(settings.value("arguments", "replay --interpreter=mi").toString()); + gdbWidget->setRRArguments(settings.value("gdbarguments", "").toString()); + } settings.endGroup(); + settings.beginGroup("printpoints"); { gdbWidget->setDprintfStyle(settings.value("style", "gdb").toString()); gdbWidget->setDprintfFunction(settings.value("function", "printf").toString()); diff --git a/src/SeerMainWindow.h b/src/SeerMainWindow.h index baa646f..7fc2b29 100644 --- a/src/SeerMainWindow.h +++ b/src/SeerMainWindow.h @@ -44,8 +44,8 @@ class SeerMainWindow : public QMainWindow, protected Ui::SeerMainWindowForm { int executablePid () const; void setExecutableConnectHostPort (const QString& executableConnectHostPort); const QString& executableConnectHostPort () const; - void setExecutableRRHostPort (const QString& executableRRHostPort); - const QString& executableRRHostPort () const; + void setExecutableRRTraceDirectory (const QString& executableRRTraceDirectory); + const QString& executableRRTraceDirectory () const; void setExecutableCoreFilename (const QString& executableCoreFilename); const QString& executableCoreFilename () const; void setExecutablePreGdbCommands (const QStringList& preGdbCommands); diff --git a/src/SeerRRConfigPage.cpp b/src/SeerRRConfigPage.cpp new file mode 100644 index 0000000..a904a8f --- /dev/null +++ b/src/SeerRRConfigPage.cpp @@ -0,0 +1,66 @@ +#include "SeerRRConfigPage.h" +#include +#include +#include + +SeerRRConfigPage::SeerRRConfigPage(QWidget* parent) : QWidget(parent) { + + // Set up the UI. + setupUi(this); + + // Connect things. + QObject::connect(rrProgramToolButton, &QToolButton::clicked, this, &SeerRRConfigPage::handleRRProgramToolButton); + + // Setup the defaults. + reset(); +} + +SeerRRConfigPage::~SeerRRConfigPage() { +} + +QString SeerRRConfigPage::rrProgram () const { + + return rrProgramLineEdit->text(); +} + +QString SeerRRConfigPage::rrArguments () const { + + return rrArgumentsLineEdit->text(); +} + +QString SeerRRConfigPage::gdbArguments () const { + + return gdbArgumentsLineEdit->text(); +} + +void SeerRRConfigPage::setRRProgram (const QString& program) { + + rrProgramLineEdit->setText(program); +} + +void SeerRRConfigPage::setRRArguments (const QString& arguments) { + + rrArgumentsLineEdit->setText(arguments); +} + +void SeerRRConfigPage::setGdbArguments (const QString& arguments) { + + gdbArgumentsLineEdit->setText(arguments); +} + +void SeerRRConfigPage::reset () { + + setRRProgram("/usr/bin/rr"); + setRRArguments("replay --interpreter=mi"); + setGdbArguments(""); +} + +void SeerRRConfigPage::handleRRProgramToolButton () { + + QString program = QFileDialog::getOpenFileName(this, "Select a RR program to use.", rrProgram(), "", nullptr, QFileDialog::DontUseNativeDialog); + + if (program != "") { + setRRProgram(program); + } +} + diff --git a/src/SeerRRConfigPage.h b/src/SeerRRConfigPage.h new file mode 100644 index 0000000..5ae869e --- /dev/null +++ b/src/SeerRRConfigPage.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "ui_SeerRRConfigPage.h" + +class SeerRRConfigPage : public QWidget, protected Ui::SeerRRConfigPage { + + Q_OBJECT + + public: + explicit SeerRRConfigPage (QWidget* parent = 0); + ~SeerRRConfigPage (); + + QString rrProgram () const; + QString rrArguments () const; + QString gdbArguments () const; + + void setRRProgram (const QString& program); + void setRRArguments (const QString& arguments); + void setGdbArguments (const QString& arguments); + + void reset (); + + protected slots: + void handleRRProgramToolButton (); +}; + diff --git a/src/SeerRRConfigPage.ui b/src/SeerRRConfigPage.ui new file mode 100644 index 0000000..641fca6 --- /dev/null +++ b/src/SeerRRConfigPage.ui @@ -0,0 +1,131 @@ + + + SeerRRConfigPage + + + + 0 + 0 + 794 + 920 + + + + SeerRRConfigPage + + + + 0 + + + 0 + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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;"><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">Specify the RR program and location, as well as the RR arguments. </span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">Changing many of these require saving the new configuration and restarting Seer to take effect</span><span style=" font-family:'Noto Sans'; font-size:10pt;">.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br />&quot;RR program&quot; points to the path and name of the RR program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;RR arguments&quot; specifies the arguments to pass to RR. It must minimally have 'replay --interpreter=mi'. And other arguments you may need for RR.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;GDB arguments&quot; specified the arguments to pass on to gdb. Usually not needed.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Between these input fields, Seer forms the command:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"> $ /usr/bin/rr replay --interpreter=mi [RR-arguments] [trace-directory] [--tty /dev/pts] [-- gdb-arguments] </span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br /></span><span style=" font-family:'Noto Sans'; font-size:10pt;">Note, Seer relies on the &quot;mi&quot; interpreter that is built into gdb. So, the &quot;--interpreter=mi&quot; argument is a must. This is specified in the &quot;RR arguments&quot; field.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br />The &quot;trace-directory&quot; argument is given when you run Seer in the RR mode.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;--tty&quot; device is handled automatically by Seer.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br />Here's the RR Wiki page for more info on arguments.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">https://github.com/rr-debugger/rr/wiki/Usage<br /><br /></span></p></body></html> + + + + + + + RR Settings + + + + + + RR program + + + + + + + Specify the path and name of the RR debugger. + + + true + + + + + + + Open a file dialog to locate the RR debugger. + + + + + + + :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/RelaxLightIcons/document-open.svg + + + + + + + RR arguments + + + + + + + Arguments to pass to the RR debugger. + + + true + + + + + + + GDB arguments + + + + + + + Any extra arguments to pass to the gdb debugger. + + + true + + + + + + + + rrGroupBox + textBrowser + + + + + + diff --git a/src/resource.qrc b/src/resource.qrc index 2c79ec1..dd44f66 100644 --- a/src/resource.qrc +++ b/src/resource.qrc @@ -5,6 +5,7 @@ resources/seergdb_128x128.png resources/seergdb_256x256.png resources/seergdb_512x512.png + resources/rr_256x256.png resources/ABOUT.md resources/thenounproject/memory.svg resources/thenounproject/source.svg diff --git a/src/resources/help/DebugModes.md b/src/resources/help/DebugModes.md index c7696d2..36aaf5b 100644 --- a/src/resources/help/DebugModes.md +++ b/src/resources/help/DebugModes.md @@ -6,7 +6,7 @@ Seer supports most debugging modes that gdb provides. These are: * Starting and running a program * Attaching to a local process on the system * Connecting to a gdbserver -* Connecting to a RR replay session +* Loading a previously created RR trace session * Loading a corefile leftover from a program that crashed ### What can you do? diff --git a/src/resources/help/seergdb.hlp b/src/resources/help/seergdb.hlp index 09b8bbd..463300a 100644 --- a/src/resources/help/seergdb.hlp +++ b/src/resources/help/seergdb.hlp @@ -26,7 +26,7 @@ Launch Options (pick one): 'sym' is optional if the debugging info is in a separate file. - --rr Connect to an already running 'rr replay -s -k' session. + --rr Load a previously created RR trace session from 'trace-directory'. --core Load a corefile. diff --git a/src/resources/rr_256x256.png b/src/resources/rr_256x256.png new file mode 100644 index 0000000..7437fa7 Binary files /dev/null and b/src/resources/rr_256x256.png differ diff --git a/src/seergdb.cpp b/src/seergdb.cpp index 204e327..df7bc78 100644 --- a/src/seergdb.cpp +++ b/src/seergdb.cpp @@ -146,7 +146,7 @@ int main (int argc, char* argv[]) { QString breakMode = "none"; int executablePid = -1; QString executableConnectHostPort; - QString executableRRHostPort; + QString executableRRTraceDirectory; QString executableSymbolFilename; QString executableBreakpointsFilename; QString executableBreakpointFunctionName; @@ -215,7 +215,7 @@ int main (int argc, char* argv[]) { if (parser.isSet(rrOption)) { launchMode = "rr"; - executableRRHostPort = parser.value(rrOption); + executableRRTraceDirectory = parser.value(rrOption); } if (parser.isSet(corefileOption)) { @@ -296,14 +296,14 @@ int main (int argc, char* argv[]) { qDebug() << "SYMBOLNAME" << executableSymbolFilename; qDebug() << "PID" << executablePid; qDebug() << "CONNECTHOST" << executableConnectHostPort; - qDebug() << "RRHOSTPORT" << executableRRHostPort; + qDebug() << "RRTRACEDIRECTORY" << executableRRTraceDirectory; qDebug() << "COREFILENAME" << executableCoreFilename; qDebug() << "PROJECTFILE" << projectFilename; qDebug() << "ARGUMENTS" << positionalArguments; seer.setExecutablePid(executablePid); seer.setExecutableConnectHostPort(executableConnectHostPort); - seer.setExecutableRRHostPort(executableRRHostPort); + seer.setExecutableRRTraceDirectory(executableRRTraceDirectory); seer.setExecutableCoreFilename(executableCoreFilename); seer.setProjectFilename(projectFilename);