Add new ThreadGroup browser.

This commit is contained in:
Ernie Pasveer
2022-09-18 12:01:01 -05:00
parent 7fcf280e96
commit 253100f9e2
11 changed files with 346 additions and 12 deletions
+81
View File
@@ -1,6 +1,22 @@
-list-thread-groups
^done,groups=[
{
id="i1",
type="process",
pid="5424",
executable="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior",
cores=["0"]
},
{ id="i2",
type="process",
pid="5432",
executable="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior",
cores=["5"]
}
]
^done,groups=[
{
id=\"i1\",
@@ -11,8 +27,73 @@
}
]
^done,groups=[
{
id="i1",
type="process",
pid="3665",
executable="/home/erniep/Development/Peak/src/Apps/Explorer/explorer",
cores=["0","2","4","5","6","7"]
}
]
-list-thread-groups --recurse 1
^done,groups=[
{
id="i1",
type="process",
pid="5424",
executable="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior",
cores=["0"],
threads=[
{
id="1",
target-id="process 5424",
name="helloinferior",
frame={
level="0",
addr="0x0000000000400702",
func="main",
args=[],
file="helloinferior.c",
fullname="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior.c",
line="11",
arch="i386:x86-64"
},
state="stopped",
core="0"
}
]
},
{
id="i2",
type="process",
pid="5432",
executable="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior",
cores=["5"],
threads=[
{
id="2",
target-id="process 5432",
name="helloinferior",
frame={
level="0",
addr="0x00007ffff7147a68",
func="fork",
args=[],
from="/lib64/libc.so.6",
arch="i386:x86-64"},
state="stopped",
core="5"
}
]
}
]
^done,groups=[
{
id=\"i1\",
+2
View File
@@ -72,6 +72,7 @@ set(HEADER_FILES
SeerStackManagerWidget.h
SeerThreadFramesBrowserWidget.h
SeerThreadIdsBrowserWidget.h
SeerThreadGroupsBrowserWidget.h
SeerThreadManagerWidget.h
SeerGdbLogWidget.h
SeerTildeLogWidget.h
@@ -154,6 +155,7 @@ set(SOURCE_FILES
SeerStackManagerWidget.cpp
SeerThreadFramesBrowserWidget.cpp
SeerThreadIdsBrowserWidget.cpp
SeerThreadGroupsBrowserWidget.cpp
SeerThreadManagerWidget.cpp
SeerGdbLogWidget.cpp
SeerTildeLogWidget.cpp
+16 -4
View File
@@ -124,8 +124,6 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) {
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, stackManagerWidget->stackLocalsBrowserWidget(), &SeerStackLocalsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, stackManagerWidget->stackArgumentsBrowserWidget(), &SeerStackArgumentsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, stackManagerWidget, &SeerStackManagerWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, threadManagerWidget->threadIdsBrowserWidget(), &SeerThreadIdsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, _breakpointsBrowserWidget, &SeerBreakpointsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, _watchpointsBrowserWidget, &SeerWatchpointsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, _catchpointsBrowserWidget, &SeerCatchpointsBrowserWidget::handleText);
@@ -137,8 +135,12 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) {
QObject::connect(_gdbMonitor, &GdbMonitor::astrixTextOutput, this, &SeerGdbWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::equalTextOutput, this, &SeerGdbWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::equalTextOutput, threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::astrixTextOutput, threadManagerWidget->threadFramesBrowserWidget(), &SeerThreadFramesBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, threadManagerWidget->threadIdsBrowserWidget(), &SeerThreadIdsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::caretTextOutput, threadManagerWidget->threadGroupsBrowserWidget(), &SeerThreadGroupsBrowserWidget::handleText);
QObject::connect(_gdbMonitor, &GdbMonitor::equalTextOutput, threadManagerWidget->threadGroupsBrowserWidget(), &SeerThreadGroupsBrowserWidget::handleText);
QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::refreshBreakpointsList, this, &SeerGdbWidget::handleGdbGenericpointList);
QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::refreshStackFrames, this, &SeerGdbWidget::handleGdbStackListFrames);
@@ -205,6 +207,7 @@ 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->threadGroupsBrowserWidget(), &SeerThreadGroupsBrowserWidget::refreshThreadGroups, this, &SeerGdbWidget::handleGdbThreadListGroups);
QObject::connect(threadManagerWidget, &SeerThreadManagerWidget::schedulerLockingModeChanged, this, &SeerGdbWidget::handleGdbSchedulerLockingMode);
QObject::connect(threadManagerWidget, &SeerThreadManagerWidget::scheduleMultipleModeChanged, this, &SeerGdbWidget::handleGdbScheduleMultipleMode);
QObject::connect(threadManagerWidget, &SeerThreadManagerWidget::forkFollowsModeChanged, this, &SeerGdbWidget::handleGdbForkFollowMode);
@@ -1452,6 +1455,15 @@ void SeerGdbWidget::handleGdbPrintpointInsert (QString printpoint) {
}
void SeerGdbWidget::handleGdbThreadListFrames () {
if (executableLaunchMode() == "") {
return;
}
handleGdbCommand("-thread-info");
}
void SeerGdbWidget::handleGdbThreadListIds () {
if (executableLaunchMode() == "") {
@@ -1461,13 +1473,13 @@ void SeerGdbWidget::handleGdbThreadListIds () {
handleGdbCommand("-thread-list-ids");
}
void SeerGdbWidget::handleGdbThreadListFrames () {
void SeerGdbWidget::handleGdbThreadListGroups () {
if (executableLaunchMode() == "") {
return;
}
handleGdbCommand("-thread-info");
handleGdbCommand("-list-thread-groups");
}
void SeerGdbWidget::handleGdbThreadSelectId (int threadid) {
+2 -1
View File
@@ -211,8 +211,9 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
void handleGdbPrintpointEnable (QString breakpoints);
void handleGdbPrintpointDisable (QString breakpoints);
void handleGdbPrintpointInsert (QString printpoint);
void handleGdbThreadListIds ();
void handleGdbThreadListFrames ();
void handleGdbThreadListIds ();
void handleGdbThreadListGroups ();
void handleGdbThreadSelectId (int threadid);
void handleGdbRegisterListNames ();
void handleGdbRegisterListValues (QString fmt);
+3
View File
@@ -643,6 +643,9 @@ void SeerMainWindow::handleText (const QString& text) {
}else if (text.startsWith("^done,threads=[")) {
return;
}else if (text.startsWith("^done,groups=[")) {
return;
}else if (text.startsWith("^done,register-names=[") && text.endsWith("]")) {
return;
+142
View File
@@ -0,0 +1,142 @@
#include "SeerThreadGroupsBrowserWidget.h"
#include "SeerUtl.h"
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItemIterator>
#include <QtWidgets/QApplication>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
SeerThreadGroupsBrowserWidget::SeerThreadGroupsBrowserWidget (QWidget* parent) : QWidget(parent) {
// Construct the UI.
setupUi(this);
// Setup the widgets
groupTreeWidget->setMouseTracking(true);
groupTreeWidget->setSortingEnabled(false);
groupTreeWidget->resizeColumnToContents(0); // id
groupTreeWidget->resizeColumnToContents(1); // type
groupTreeWidget->resizeColumnToContents(2); // pid
groupTreeWidget->resizeColumnToContents(3); // executable
groupTreeWidget->resizeColumnToContents(4); // cores
groupTreeWidget->clear();
// Connect things.
QObject::connect(groupTreeWidget, &QTreeWidget::itemEntered, this, &SeerThreadGroupsBrowserWidget::handleItemEntered);
}
SeerThreadGroupsBrowserWidget::~SeerThreadGroupsBrowserWidget () {
}
void SeerThreadGroupsBrowserWidget::handleText (const QString& text) {
// Don't do any work if the widget is hidden.
if (isHidden()) {
return;
}
QApplication::setOverrideCursor(Qt::BusyCursor);
if (text.startsWith("^done,groups=[")) {
// ^done,groups=[
// {
// id="i1",
// type="process",
// pid="5424",
// executable="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior",
// cores=["0"]
// },
// { id="i2",
// type="process",
// pid="5432",
// executable="/home/erniep/Development/Peak/src/seer/tests/helloinferior/helloinferior",
// cores=["5"]
// }
// ]
//qDebug() << text;
groupTreeWidget->clear();
QString groups_text = Seer::parseFirst(text, "groups=", '[', ']', false);
//qDebug() << groups_text;
if (groups_text != "") {
QStringList groups_list = Seer::parse(groups_text, "", '{', '}', false);
for ( const auto& group_text : groups_list ) {
QString id_text = Seer::parseFirst(group_text, "id=", '"', '"', false);
QString type_text = Seer::parseFirst(group_text, "type=", '"', '"', false);
QString pid_text = Seer::parseFirst(group_text, "pid=", '"', '"', false);
QString exe_text = Seer::parseFirst(group_text, "executable=", '"', '"', false);
QString cores_text = Seer::parseFirst(group_text, "cores=", '[', ']', false);
// Create the item.
QTreeWidgetItem* item = new QTreeWidgetItem;
item->setText(0, id_text);
item->setText(1, type_text);
item->setText(2, pid_text);
item->setText(3, exe_text);
item->setText(4, cores_text);
// Add the frame to the tree.
groupTreeWidget->addTopLevelItem(item);
}
}
}else if (text.startsWith("=thread-created,id=")) {
// =thread-created,id="2",group-id="i2"
refresh();
}else if (text.startsWith("=thread-exited,id=")) {
// =thread-exited,id="2",group-id="i2"
refresh();
}else if (text.startsWith("^error,msg=\"No registers.\"")) {
groupTreeWidget->clear();
}else{
// Ignore others.
}
groupTreeWidget->resizeColumnToContents(0);
groupTreeWidget->resizeColumnToContents(1);
groupTreeWidget->resizeColumnToContents(2);
//groupTreeWidget->resizeColumnToContents(3); // Don't resize.
groupTreeWidget->resizeColumnToContents(4);
QApplication::restoreOverrideCursor();
}
void SeerThreadGroupsBrowserWidget::refresh () {
emit refreshThreadIds();
emit refreshThreadGroups();
}
void SeerThreadGroupsBrowserWidget::handleItemEntered (QTreeWidgetItem* item, int column) {
Q_UNUSED(column);
//qDebug() << item->text(0) << column;
item->setToolTip(0, item->text(0) + " : " + item->text(1) + " : " + item->text(2) + " : " + item->text(3) + " : " + item->text(4));
for (int i=1; i<groupTreeWidget->columnCount(); i++) { // Copy tooltip to other columns.
item->setToolTip(i, item->toolTip(0));
}
}
void SeerThreadGroupsBrowserWidget::showEvent (QShowEvent* event) {
QWidget::showEvent(event);
refresh();
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <QtWidgets/QWidget>
#include <QtCore/QString>
#include "ui_SeerThreadGroupsBrowserWidget.h"
class SeerThreadGroupsBrowserWidget : public QWidget, protected Ui::SeerThreadGroupsBrowserWidgetForm {
Q_OBJECT
public:
explicit SeerThreadGroupsBrowserWidget (QWidget* parent = 0);
~SeerThreadGroupsBrowserWidget ();
public slots:
void handleText (const QString& text);
void refresh ();
protected slots:
void handleItemEntered (QTreeWidgetItem* item, int column);
signals:
void refreshThreadGroups ();
void refreshThreadIds ();
protected:
void showEvent (QShowEvent* event);
private:
};
+53
View File
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SeerThreadGroupsBrowserWidgetForm</class>
<widget class="QWidget" name="SeerThreadGroupsBrowserWidgetForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>794</width>
<height>528</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QTreeWidget" name="groupTreeWidget">
<property name="columnCount">
<number>5</number>
</property>
<column>
<property name="text">
<string>Thread Id</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Pid</string>
</property>
</column>
<column>
<property name="text">
<string>Executable</string>
</property>
</column>
<column>
<property name="text">
<string>Cores</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+1 -1
View File
@@ -21,7 +21,7 @@
</property>
<column>
<property name="text">
<string>Id</string>
<string>Thread Id</string>
</property>
</column>
</widget>
+9 -2
View File
@@ -16,9 +16,11 @@ SeerThreadManagerWidget::SeerThreadManagerWidget (QWidget* parent) : QWidget(par
_threadFramesBrowserWidget = new SeerThreadFramesBrowserWidget(this);
_threadIdsBrowserWidget = new SeerThreadIdsBrowserWidget(this);
_threadGroupsBrowserWidget = new SeerThreadGroupsBrowserWidget(this);
tabWidget->addTab(_threadFramesBrowserWidget, "Frames");
tabWidget->addTab(_threadIdsBrowserWidget, "Ids");
tabWidget->addTab(_threadGroupsBrowserWidget, "Groups");
QToolButton* refreshToolButton = new QToolButton(tabWidget);
refreshToolButton->setIcon(QIcon(":/seer/resources/RelaxLightIcons/view-refresh.svg"));
@@ -35,12 +37,16 @@ SeerThreadManagerWidget::SeerThreadManagerWidget (QWidget* parent) : QWidget(par
SeerThreadManagerWidget::~SeerThreadManagerWidget () {
}
SeerThreadFramesBrowserWidget* SeerThreadManagerWidget::threadFramesBrowserWidget () {
return _threadFramesBrowserWidget;
}
SeerThreadIdsBrowserWidget* SeerThreadManagerWidget::threadIdsBrowserWidget () {
return _threadIdsBrowserWidget;
}
SeerThreadFramesBrowserWidget* SeerThreadManagerWidget::threadFramesBrowserWidget () {
return _threadFramesBrowserWidget;
SeerThreadGroupsBrowserWidget* SeerThreadManagerWidget::threadGroupsBrowserWidget () {
return _threadGroupsBrowserWidget;
}
void SeerThreadManagerWidget::setSchedulerLockingMode (const QString& mode) {
@@ -77,6 +83,7 @@ void SeerThreadManagerWidget::handleRefreshToolButtonClicked () {
threadFramesBrowserWidget()->refresh();
threadIdsBrowserWidget()->refresh();
threadGroupsBrowserWidget()->refresh();
}
void SeerThreadManagerWidget::handleSchedulerLockingComboBox (int index) {
+6 -4
View File
@@ -1,7 +1,8 @@
#pragma once
#include "SeerThreadIdsBrowserWidget.h"
#include "SeerThreadFramesBrowserWidget.h"
#include "SeerThreadIdsBrowserWidget.h"
#include "SeerThreadGroupsBrowserWidget.h"
#include <QtWidgets/QWidget>
@@ -15,15 +16,15 @@ class SeerThreadManagerWidget : public QWidget, protected Ui::SeerThreadManagerW
explicit SeerThreadManagerWidget (QWidget* parent = 0);
~SeerThreadManagerWidget ();
SeerThreadIdsBrowserWidget* threadIdsBrowserWidget ();
SeerThreadFramesBrowserWidget* threadFramesBrowserWidget ();
SeerThreadIdsBrowserWidget* threadIdsBrowserWidget ();
SeerThreadGroupsBrowserWidget* threadGroupsBrowserWidget ();
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;
@@ -41,7 +42,8 @@ class SeerThreadManagerWidget : public QWidget, protected Ui::SeerThreadManagerW
void handleForkFollowComboBox (int index);
private:
SeerThreadIdsBrowserWidget* _threadIdsBrowserWidget;
SeerThreadFramesBrowserWidget* _threadFramesBrowserWidget;
SeerThreadIdsBrowserWidget* _threadIdsBrowserWidget;
SeerThreadGroupsBrowserWidget* _threadGroupsBrowserWidget;
};