diff --git a/notes/README.logging b/notes/README.logging index ce92a6a..9e3db6e 100644 --- a/notes/README.logging +++ b/notes/README.logging @@ -22,5 +22,9 @@ Turn on logging like this: % export QT_LOGGING_RULES="seer.*.debug=false;seer.seergdbwidget.debug=true" % export QT_LOGGING_RULES="seer.*.debug=false;seer.gdbmonitor.debug=true" +To turn on simple logging of qDebug(), et al, set this: + + % export QT_LOGGING_RULES="default.debug=true" + Then start seer. There should be lots of debug output. diff --git a/src/SeerDebugDialog.cpp b/src/SeerDebugDialog.cpp index ccd8f0e..22e60f7 100644 --- a/src/SeerDebugDialog.cpp +++ b/src/SeerDebugDialog.cpp @@ -23,6 +23,7 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) { // Setup the widgets setExecutableName(""); setExecutableArguments(""); + setBreakpointsFilename(""); setExecutableWorkingDirectory(QDir::currentPath()); setBreakInMain(true); setAttachPid(0); @@ -32,6 +33,7 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) { // Connect things. QObject::connect(executableNameToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleExecutableNameToolButton); QObject::connect(executableWorkingDirectoryToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleExecutableWorkingDirectoryToolButton); + QObject::connect(loadBreakpointsFilenameToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleLoadBreakpointsFilenameToolButton); QObject::connect(loadCoreFilenameToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleLoadCoreFilenameToolButton); QObject::connect(attachProgramPidToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleProgramPidToolButton); QObject::connect(_runModeButtonGroup, QOverload::of(&QButtonGroup::buttonClicked), this, &SeerDebugDialog::handleRunModeChanged); @@ -67,6 +69,14 @@ QString SeerDebugDialog::executableArguments () const { return runProgramArgumentsLineEdit->text(); } +void SeerDebugDialog::setBreakpointsFilename (const QString& breakpointsFilename) { + loadBreakpointsFilenameLineEdit->setText(breakpointsFilename); +} + +QString SeerDebugDialog::breakpointsFilename () const { + return loadBreakpointsFilenameLineEdit->text(); +} + void SeerDebugDialog::setBreakInMain (bool flag) { runProgramBreakInMainCheckBox->setChecked(flag); } @@ -238,6 +248,15 @@ void SeerDebugDialog::handleExecutableWorkingDirectoryToolButton () { } } +void SeerDebugDialog::handleLoadBreakpointsFilenameToolButton () { + + QString name = QFileDialog::getOpenFileName(this, "Select a breakpoints file to load.", breakpointsFilename(), "Breakpoints (*.brk);;All files (*.*)", nullptr, QFileDialog::DontUseNativeDialog); + + if (name != "") { + setBreakpointsFilename(name); + } +} + void SeerDebugDialog::handleLoadCoreFilenameToolButton () { QString name = QFileDialog::getOpenFileName(this, "Select a core file to debug.", coreFilename(), "Core Files (core core.*)", nullptr, QFileDialog::DontUseNativeDialog); diff --git a/src/SeerDebugDialog.h b/src/SeerDebugDialog.h index 485cbf6..63cf7e8 100644 --- a/src/SeerDebugDialog.h +++ b/src/SeerDebugDialog.h @@ -24,6 +24,8 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { // Run or start executable. "run" or "start". void setExecutableArguments (const QString& executableArguments); QString executableArguments () const; + void setBreakpointsFilename (const QString& breakpointsFilename); + QString breakpointsFilename () const; void setBreakInMain (bool flag); bool breakInMain () const; @@ -48,6 +50,7 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm { protected slots: void handleExecutableNameToolButton (); void handleExecutableWorkingDirectoryToolButton (); + void handleLoadBreakpointsFilenameToolButton (); void handleLoadCoreFilenameToolButton (); void handleProgramPidToolButton (); void handleRunModeChanged (int id); diff --git a/src/SeerDebugDialog.ui b/src/SeerDebugDialog.ui index 4c52e77..7a8d7f8 100644 --- a/src/SeerDebugDialog.ui +++ b/src/SeerDebugDialog.ui @@ -7,7 +7,7 @@ 0 0 596 - 612 + 620 @@ -58,7 +58,7 @@ - :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/HighContrast/document-open.svg + :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/RelaxLightIcons/document-open.svg @@ -97,7 +97,7 @@ - :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/HighContrast/document-open.svg + :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/RelaxLightIcons/document-open.svg @@ -116,132 +116,7 @@ Launch Method - - - - Attach to an already running program. - - - Attach program - - - - - - - Qt::Horizontal - - - - - - - The path and name of a core file. - - - true - - - - - - - Qt::Horizontal - - - - - - - Core - - - - - - - Qt::Horizontal - - - - - - - Download the executable used by the gdbserver. - - - Download - - - - - - - Connect to an already running program with gdbserver. - - - Connect program - - - - - - - Load a core file to debug. - - - Load a core file - - - - - - - Open a dialog to select a pid on the local system. - - - ... - - - - - - - The arguments to pass to the program. - - - true - - - - - - - Open a dialog to select a core file. - - - - - - - :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/HighContrast/document-open.svg - - - - - - - Qt::Horizontal - - - - 278 - 20 - - - - - + Run the program. @@ -251,26 +126,6 @@ - - - - Qt::Horizontal - - - - 230 - 20 - - - - - - - - Process PID - - - @@ -278,7 +133,38 @@ - + + + + Breakpoints + + + + + + + A file containing previously saved breakpoints. + + + true + + + + + + + Open a dialog to select a breakpoints file. + + + + + + + :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/RelaxLightIcons/document-open.svg + + + + Set a breakpoint in main() before running program. @@ -294,7 +180,31 @@ - + + + + Qt::Horizontal + + + + + + + Attach to an already running program. + + + Attach program + + + + + + + Process PID + + + + The process pid. @@ -310,14 +220,54 @@ - + + + + Open a dialog to select a pid on the local system. + + + ... + + + + + + + Qt::Horizontal + + + + 278 + 20 + + + + + + + + Qt::Horizontal + + + + + + + Connect to an already running program with gdbserver. + + + Connect program + + + + Gdbserver - + The name of the remote host where gdbserver has already been started. @@ -333,6 +283,87 @@ + + + + Qt::Horizontal + + + + 230 + 20 + + + + + + + + Download the executable used by the gdbserver. + + + Download + + + + + + + Qt::Horizontal + + + + + + + Load a core file to debug. + + + Load a core file + + + + + + + Core + + + + + + + The path and name of a core file. + + + true + + + + + + + Open a dialog to select a core file. + + + + + + + :/seer/resources/RelaxLightIcons/document-open.svg:/seer/resources/RelaxLightIcons/document-open.svg + + + + + + + The arguments to pass to the program. + + + true + + + diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp index 2571ea9..52a2c05 100644 --- a/src/SeerGdbWidget.cpp +++ b/src/SeerGdbWidget.cpp @@ -26,6 +26,8 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) { _executableName = ""; _executableArguments = ""; _executableWorkingDirectory = ""; + _executableBreakpointsFilename = ""; + _executableCoreFilename = ""; _executablePid = 0; _gdbMonitor = 0; _gdbProcess = 0; @@ -276,6 +278,14 @@ const QString& SeerGdbWidget::executableWorkingDirectory () const { return _executableWorkingDirectory; } +void SeerGdbWidget::setExecutableBreakpointsFilename (const QString& breakpointsFilename) { + _executableBreakpointsFilename = breakpointsFilename; +} + +const QString& SeerGdbWidget::executableBreakpointsFilename () const { + return _executableBreakpointsFilename; +} + void SeerGdbWidget::setExecutablePid (int pid) { _executablePid = pid; } @@ -505,6 +515,7 @@ void SeerGdbWidget::handleGdbRunExecutable () { handleGdbExecutableSources(); // Load the program source files. handleGdbExecutableArguments(); // Set the program's arguments before running. handleGdbExecutableWorkingDirectory(); // Set the program's working directory before running. + handleGdbExecutableLoadBreakpoints(); // Set the program's breakpoints (if any) before running. } setNewExecutableFlag(false); @@ -579,6 +590,7 @@ void SeerGdbWidget::handleGdbStartExecutable () { handleGdbExecutableSources(); // Load the program source files. handleGdbExecutableArguments(); // Set the program's arguments before running. handleGdbExecutableWorkingDirectory(); // Set the program's working directory before running. + handleGdbExecutableLoadBreakpoints(); // Set the program's breakpoints (if any) before running. } setNewExecutableFlag(false); @@ -932,6 +944,16 @@ void SeerGdbWidget::handleGdbExecutableWorkingDirectory () { } } +void SeerGdbWidget::handleGdbExecutableLoadBreakpoints () { + + if (executableBreakpointsFilename() == "") { + return; + } + + handleGdbCommand("source -v " + executableBreakpointsFilename()); + handleGdbGenericpointList(); +} + void SeerGdbWidget::handleGdbTtyDeviceName () { if (_consoleWidget->ttyDeviceName() != "") { diff --git a/src/SeerGdbWidget.h b/src/SeerGdbWidget.h index 6ca0c27..874482d 100644 --- a/src/SeerGdbWidget.h +++ b/src/SeerGdbWidget.h @@ -37,6 +37,9 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void setExecutableWorkingDirectory (const QString& executableWorkingDirectory); const QString& executableWorkingDirectory () const; + void setExecutableBreakpointsFilename (const QString& breakpointsFilename); + const QString& executableBreakpointsFilename () const; + void setExecutablePid (int pid); int executablePid () const; @@ -129,6 +132,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void handleGdbExecutableName (); void handleGdbExecutableArguments (); void handleGdbExecutableWorkingDirectory (); + void handleGdbExecutableLoadBreakpoints (); void handleGdbTtyDeviceName (); void handleGdbStackListFrames (); void handleGdbStackSelectFrame (int frameno); @@ -204,6 +208,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { QString _executableName; QString _executableArguments; QString _executableWorkingDirectory; + QString _executableBreakpointsFilename; int _executablePid; QString _executableHostPort; QString _executableCoreFilename; diff --git a/src/SeerMainWindow.cpp b/src/SeerMainWindow.cpp index cb1759b..7cd9471 100644 --- a/src/SeerMainWindow.cpp +++ b/src/SeerMainWindow.cpp @@ -176,6 +176,14 @@ const QString& SeerMainWindow::executableWorkingDirectory () const { return gdbWidget->executableWorkingDirectory(); } +void SeerMainWindow::setExecutableBreakpointsFilename (const QString& breakpointsFilename) { + gdbWidget->setExecutableBreakpointsFilename(breakpointsFilename); +} + +const QString& SeerMainWindow::executableBreakpointsFilename () const { + return gdbWidget->executableBreakpointsFilename(); +} + void SeerMainWindow::setExecutablePid (int pid) { gdbWidget->setExecutablePid(pid); } @@ -238,6 +246,7 @@ void SeerMainWindow::handleFileDebug () { dlg.setExecutableName(executableName()); dlg.setExecutableWorkingDirectory(executableWorkingDirectory()); dlg.setExecutableArguments(executableArguments()); + dlg.setBreakpointsFilename(executableBreakpointsFilename()); dlg.setAttachPid(executablePid()); dlg.setConnectHostPort(executableHostPort()); dlg.setCoreFilename(executableCoreFilename()); @@ -258,6 +267,7 @@ void SeerMainWindow::handleFileDebug () { setExecutableName(dlg.executableName()); setExecutableWorkingDirectory(dlg.executableWorkingDirectory()); setExecutableArguments(dlg.executableArguments()); + setExecutableBreakpointsFilename(dlg.breakpointsFilename()); setExecutablePid(dlg.attachPid()); setExecutableHostPort(dlg.connectHostPort()); setExecutableCoreFilename(dlg.coreFilename()); diff --git a/src/SeerMainWindow.h b/src/SeerMainWindow.h index ce87648..44bdebd 100644 --- a/src/SeerMainWindow.h +++ b/src/SeerMainWindow.h @@ -19,48 +19,50 @@ class SeerMainWindow : public QMainWindow, protected Ui::SeerMainWindowForm { SeerMainWindow (QWidget* parent = 0); ~SeerMainWindow (); - void setExecutableName (const QString& executableName); - const QString& executableName () const; - void setExecutableArguments (const QString& executableArguments); - void setExecutableArguments (const QStringList& executableArguments); - const QString& executableArguments () const; - void setExecutableWorkingDirectory (const QString& executableWorkingDirectory); - const QString& executableWorkingDirectory () const; - void setExecutablePid (int pid); - int executablePid () const; - void setExecutableHostPort (const QString& executableHostPort); - const QString& executableHostPort () const; - void setExecutableCoreFilename (const QString& executableCoreFilename); - const QString& executableCoreFilename () const; + void setExecutableName (const QString& executableName); + const QString& executableName () const; + void setExecutableArguments (const QString& executableArguments); + void setExecutableArguments (const QStringList& executableArguments); + const QString& executableArguments () const; + void setExecutableWorkingDirectory (const QString& executableWorkingDirectory); + const QString& executableWorkingDirectory () const; + void setExecutableBreakpointsFilename (const QString& breakpointsFilename); + const QString& executableBreakpointsFilename () const; + void setExecutablePid (int pid); + int executablePid () const; + void setExecutableHostPort (const QString& executableHostPort); + const QString& executableHostPort () const; + void setExecutableCoreFilename (const QString& executableCoreFilename); + const QString& executableCoreFilename () const; - void launchExecutable (const QString& launchMode); - const QString& executableLaunchMode () const; + void launchExecutable (const QString& launchMode); + const QString& executableLaunchMode () const; private slots: - void handleFileDebug (); - void handleFileArguments (); - void handleFileQuit (); - void handleViewMemoryVisualizer (); - void handleViewArrayVisualizer (); - void handleViewConsoleNormal (); - void handleViewConsoleHidden (); - void handleViewConsoleMinimized (); - void handleSettingsConfiguration (); - void handleSettingsSaveConfiguration (); - void handleHelpAbout (); - void handleText (const QString& text); - void handleRunStatusChanged (SeerRunStatusIndicator::RunStatus status); + void handleFileDebug (); + void handleFileArguments (); + void handleFileQuit (); + void handleViewMemoryVisualizer (); + void handleViewArrayVisualizer (); + void handleViewConsoleNormal (); + void handleViewConsoleHidden (); + void handleViewConsoleMinimized (); + void handleSettingsConfiguration (); + void handleSettingsSaveConfiguration (); + void handleHelpAbout (); + void handleText (const QString& text); + void handleRunStatusChanged (SeerRunStatusIndicator::RunStatus status); protected: - void writeSettings (); - void readSettings (); - void writeConfigSettings (); - void readConfigSettings (); - void resizeEvent (QResizeEvent* event); - void closeEvent (QCloseEvent* event); - void setKeySettings (const SeerKeySettings& settings); - const SeerKeySettings keySettings () const; - void refreshShortCuts (); + void writeSettings (); + void readSettings (); + void writeConfigSettings (); + void readConfigSettings (); + void resizeEvent (QResizeEvent* event); + void closeEvent (QCloseEvent* event); + void setKeySettings (const SeerKeySettings& settings); + const SeerKeySettings keySettings () const; + void refreshShortCuts (); private: QProgressIndicator* _progressIndicator; diff --git a/src/seer.cpp b/src/seer.cpp index d2c7e0e..9f8dbae 100644 --- a/src/seer.cpp +++ b/src/seer.cpp @@ -46,6 +46,9 @@ int main (int argc, char* argv[]) { QCommandLineOption startOption(QStringList()<<"s"<<"start", QCoreApplication::translate("main", "Load the executable, break in main(), and run it.")); parser.addOption(startOption); + QCommandLineOption breakpointsOption(QStringList()<<"b"<<"breakpoints", QCoreApplication::translate("main", "Optionally load a previously saved breakpoints file. For --run or --start"), "filename"); + parser.addOption(breakpointsOption); + QCommandLineOption attachOption(QStringList()<<"attach", QCoreApplication::translate("main", "Attach to a running process."), "pid"); parser.addOption(attachOption); @@ -78,6 +81,7 @@ int main (int argc, char* argv[]) { QString launchMode = "none"; int executablePid = -1; QString executableHostPort; + QString executableBreakpointsFilename; QString executableCoreFilename; if (parser.isSet(runOption)) { @@ -88,6 +92,10 @@ int main (int argc, char* argv[]) { launchMode = "start"; } + if (parser.isSet(breakpointsOption)) { + executableBreakpointsFilename = parser.value(breakpointsOption); + } + if (parser.isSet(attachOption)) { launchMode = "attach"; @@ -116,6 +124,7 @@ int main (int argc, char* argv[]) { seer.setWindowIcon(QIcon(":/seer/resources/seer_64x64.png")); seer.setExecutableName(executableName); seer.setExecutableArguments(positionalArguments); + seer.setExecutableBreakpointsFilename(executableBreakpointsFilename); seer.setExecutablePid(executablePid); seer.setExecutableHostPort(executableHostPort); seer.setExecutableCoreFilename(executableCoreFilename);