From 65ef10f10f2ea3b96588d0b2d6ceaa12916a6dbb Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 17 Sep 2022 09:14:46 -0500 Subject: [PATCH] Add support for stepping through all threads or a selected thread. --- CHANGELOG.md | 16 +++- src/SeerGdbWidget.cpp | 26 ++++++- src/SeerGdbWidget.h | 2 + src/SeerThreadFramesBrowserWidget.cpp | 8 +- src/SeerThreadManagerWidget.cpp | 40 +++++++++- src/SeerThreadManagerWidget.h | 11 ++- src/SeerThreadManagerWidget.ui | 103 ++++++++++++++++++++++---- 7 files changed, 181 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index addf66e..f5b5e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,20 @@ # Seer Change Log ## [1.11beta] - 2022-XX-22 -* . - - . +* Thread/Process manager. + - Add a fork/vfork mode. Follow: + - Parent process. + - Child process. + - Both (switchable via thread manager) + - (see gdb's follow-fork-mode and detach-on-fork modes) + - Add thread execution mode. Execute: + - Selected thread only. + - All threads + - (see gdb's scheduler-locking mode) + - Add multi-process execution mode. + - Execute selected process. + - Execute all processes. + - (see gdb's schedule-multiple mode) ## [1.10] - 2022-09-22 * New Struct Visualizer. diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp index ddd539c..22cfe09 100644 --- a/src/SeerGdbWidget.cpp +++ b/src/SeerGdbWidget.cpp @@ -205,6 +205,8 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) { QObject::connect(threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::refreshThreadFrames, this, &SeerGdbWidget::handleGdbThreadListFrames); QObject::connect(threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::selectedFile, editorManagerWidget, &SeerEditorManagerWidget::handleOpenFile); QObject::connect(threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::selectedThread, this, &SeerGdbWidget::handleGdbThreadSelectId); + QObject::connect(threadManagerWidget, &SeerThreadManagerWidget::schedulerLockingModeChanged, this, &SeerGdbWidget::handleGdbSchedulerLockingMode); + QObject::connect(threadManagerWidget, &SeerThreadManagerWidget::scheduleMultipleModeChanged, this, &SeerGdbWidget::handleGdbScheduleMultipleMode); QObject::connect(threadManagerWidget, &SeerThreadManagerWidget::forkFollowsModeChanged, this, &SeerGdbWidget::handleGdbForkFollowMode); QObject::connect(_breakpointsBrowserWidget, &SeerBreakpointsBrowserWidget::refreshBreakpointsList, this, &SeerGdbWidget::handleGdbGenericpointList); @@ -2500,19 +2502,37 @@ void SeerGdbWidget::setAssemblySymbolDemagling (const QString& onoff) { } } +void SeerGdbWidget::handleGdbSchedulerLockingMode (QString mode) { + + if (executableLaunchMode() == "") { + return; + } + + handleGdbCommand(QString("-gdb-set scheduler-locking %1").arg(mode)); +} + +void SeerGdbWidget::handleGdbScheduleMultipleMode (QString mode) { + + if (executableLaunchMode() == "") { + return; + } + + handleGdbCommand(QString("-gdb-set schedule-multiple %1").arg(mode)); +} + void SeerGdbWidget::handleGdbForkFollowMode (QString mode) { if (executableLaunchMode() == "") { return; } - if (mode == "Parent") { + if (mode == "parent") { handleGdbCommand("-gdb-set follow-fork-mode parent"); handleGdbCommand("-gdb-set detach-on-fork on"); - }else if (mode == "Child") { + }else if (mode == "child") { handleGdbCommand("-gdb-set follow-fork-mode child"); handleGdbCommand("-gdb-set detach-on-fork on"); - }else if (mode == "Both") { + }else if (mode == "both") { handleGdbCommand("-gdb-set follow-fork-mode parent"); handleGdbCommand("-gdb-set detach-on-fork off"); }else{ diff --git a/src/SeerGdbWidget.h b/src/SeerGdbWidget.h index 8a6deae..015d226 100644 --- a/src/SeerGdbWidget.h +++ b/src/SeerGdbWidget.h @@ -247,6 +247,8 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void handleGdbSaveBreakpoints (); void handleGdbAssemblyDisassemblyFlavor (); void handleGdbAssemblySymbolDemangling (); + void handleGdbSchedulerLockingMode (QString mode); + void handleGdbScheduleMultipleMode (QString mode); void handleGdbForkFollowMode (QString mode); void handleGdbProcessFinished (int exitCode, QProcess::ExitStatus exitStatus); diff --git a/src/SeerThreadFramesBrowserWidget.cpp b/src/SeerThreadFramesBrowserWidget.cpp index c8b5cdb..b0c45d6 100644 --- a/src/SeerThreadFramesBrowserWidget.cpp +++ b/src/SeerThreadFramesBrowserWidget.cpp @@ -176,11 +176,11 @@ void SeerThreadFramesBrowserWidget::handleText (const QString& text) { threadTreeWidget->resizeColumnToContents(0); threadTreeWidget->resizeColumnToContents(1); threadTreeWidget->resizeColumnToContents(2); - threadTreeWidget->resizeColumnToContents(3); - threadTreeWidget->resizeColumnToContents(4); + //threadTreeWidget->resizeColumnToContents(3); // Don't resize. + //threadTreeWidget->resizeColumnToContents(4); // Don't resize. threadTreeWidget->resizeColumnToContents(5); - threadTreeWidget->resizeColumnToContents(6); - //threadTreeWidget->resizeColumnToContents(7); // Don't resize args. + //threadTreeWidget->resizeColumnToContents(6); // Don't resize. + //threadTreeWidget->resizeColumnToContents(7); // Don't resize. threadTreeWidget->resizeColumnToContents(8); threadTreeWidget->resizeColumnToContents(9); threadTreeWidget->resizeColumnToContents(10); diff --git a/src/SeerThreadManagerWidget.cpp b/src/SeerThreadManagerWidget.cpp index a179c57..8f7d562 100644 --- a/src/SeerThreadManagerWidget.cpp +++ b/src/SeerThreadManagerWidget.cpp @@ -26,8 +26,10 @@ SeerThreadManagerWidget::SeerThreadManagerWidget (QWidget* parent) : QWidget(par tabWidget->setCornerWidget(refreshToolButton, Qt::TopRightCorner); // Connect things. - QObject::connect(refreshToolButton, &QToolButton::clicked, this, &SeerThreadManagerWidget::handleRefreshToolButtonClicked); - QObject::connect(forkFollowsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &SeerThreadManagerWidget::handleForkFollowComboBox); + QObject::connect(refreshToolButton, &QToolButton::clicked, this, &SeerThreadManagerWidget::handleRefreshToolButtonClicked); + QObject::connect(schedulerLockingComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &SeerThreadManagerWidget::handleSchedulerLockingComboBox); + QObject::connect(scheduleMultipleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &SeerThreadManagerWidget::handleScheduleMultipleComboBox); + QObject::connect(forkFollowsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &SeerThreadManagerWidget::handleForkFollowComboBox); } SeerThreadManagerWidget::~SeerThreadManagerWidget () { @@ -41,6 +43,26 @@ SeerThreadFramesBrowserWidget* SeerThreadManagerWidget::threadFramesBrowserWidge return _threadFramesBrowserWidget; } +void SeerThreadManagerWidget::setSchedulerLockingMode (const QString& mode) { + + schedulerLockingComboBox->setCurrentText(mode); +} + +QString SeerThreadManagerWidget::schedulerLockingMode () const { + + return schedulerLockingComboBox->currentText(); +} + +void SeerThreadManagerWidget::setScheduleMultipleMode (const QString& mode) { + + scheduleMultipleComboBox->setCurrentText(mode); +} + +QString SeerThreadManagerWidget::scheduleMultipleMode () const { + + return scheduleMultipleComboBox->currentText(); +} + void SeerThreadManagerWidget::setForkFollowsMode (const QString& mode) { forkFollowsComboBox->setCurrentText(mode); @@ -57,6 +79,20 @@ void SeerThreadManagerWidget::handleRefreshToolButtonClicked () { threadIdsBrowserWidget()->refresh(); } +void SeerThreadManagerWidget::handleSchedulerLockingComboBox (int index) { + + Q_UNUSED(index); + + emit schedulerLockingModeChanged(schedulerLockingComboBox->currentText()); +} + +void SeerThreadManagerWidget::handleScheduleMultipleComboBox (int index) { + + Q_UNUSED(index); + + emit scheduleMultipleModeChanged(scheduleMultipleComboBox->currentText()); +} + void SeerThreadManagerWidget::handleForkFollowComboBox (int index) { Q_UNUSED(index); diff --git a/src/SeerThreadManagerWidget.h b/src/SeerThreadManagerWidget.h index 0308199..df37a31 100644 --- a/src/SeerThreadManagerWidget.h +++ b/src/SeerThreadManagerWidget.h @@ -19,16 +19,25 @@ class SeerThreadManagerWidget : public QWidget, protected Ui::SeerThreadManagerW SeerThreadFramesBrowserWidget* threadFramesBrowserWidget (); signals: + void schedulerLockingModeChanged (const QString& mode); + void scheduleMultipleModeChanged (const QString& mode); void forkFollowsModeChanged (const QString& mode); public slots: + void setSchedulerLockingMode (const QString& mode); + QString schedulerLockingMode () const; + + void setScheduleMultipleMode (const QString& mode); + QString scheduleMultipleMode () const; + void setForkFollowsMode (const QString& mode); QString forkFollowsMode () const; - private slots: void handleRefreshToolButtonClicked (); + void handleSchedulerLockingComboBox (int index); + void handleScheduleMultipleComboBox (int index); void handleForkFollowComboBox (int index); private: diff --git a/src/SeerThreadManagerWidget.ui b/src/SeerThreadManagerWidget.ui index aefc1fb..ce5cbf7 100644 --- a/src/SeerThreadManagerWidget.ui +++ b/src/SeerThreadManagerWidget.ui @@ -6,7 +6,7 @@ 0 0 - 854 + 748 571 @@ -25,50 +25,127 @@ Thread/Process Info - - + + -1 - - - + + + + + + Scheduler locking: + + + + + + + Set the scheduler locking mode. + + + + replay + + + + + off + + + + + on + + + + + step + + + + + + + + + + + Schedule multiple: + + + + + + + Set the mode for allowing threads of multiple processes to be resumed when an execution command is issued. + + + + off + + + + + on + + + + + + + + Qt::Horizontal + + + + 288 + 20 + + + + + Fork follows: - + + + Set the debugger response to a program call of fork or vfork. + - Parent + parent - Child + child - Both + both - - + + Qt::Horizontal - 40 + 508 20