Add 'catchpoint' support.

Still working on editor config options.
This commit is contained in:
Ernie Pasveer
2021-12-31 13:00:02 -06:00
parent 2737f9f925
commit 07f2f0176b
7 changed files with 1228 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
# Setting a catchpoint.
-catch-throw
-catch-throw [ -t ] [ -r regexp]
-catch-rethrow [ -t ] [ -r regexp]
-catch-catch [ -t ] [ -r regexp]
# When a catchpoint is reached.
*stopped,bkptno="2",reason="breakpoint-hit",disp="keep",frame={addr="0x00007fffed933b72",func="__cxa_throw",args=[],from="/usr/lib64/libstdc++.so.6",arch="i386:x86-64"},thread-id="1",stopped-threads="all",core="5"
# List catchpoints using the same method as listing breakpoints and watchpoints, except a different 'type'.
-break-list
+208
View File
@@ -0,0 +1,208 @@
#include "SeerCatchpointCreateDialog.h"
#include <QtCore/QDebug>
SeerCatchpointCreateDialog::SeerCatchpointCreateDialog (QWidget* parent) : QDialog(parent) {
// Set up the UI.
setupUi(this);
// Setup the widgets
setFilename("");
setFunctionName("");
setLabelName("");
setLineNumber("");
setTemporaryEnabled (false);
setHardwareEnabled (false);
setPendingEnabled (false);
setDisabledEnabled (false);
setConditionalEnabled (false);
setIgnoreCountEnabled (false);
setThreadIdEnabled (false);
setConditionalText ("");
setIgnoreCountText ("");
setThreadIdText ("");
// Connect things.
QObject::connect(conditionalCheckBox, &QCheckBox::clicked, conditionalLineEdit, &QLineEdit::setEnabled);
QObject::connect(ignoreCountCheckBox, &QCheckBox::clicked, ignoreCountLineEdit, &QLineEdit::setEnabled);
QObject::connect(threadIdCheckBox, &QCheckBox::clicked, threadIdLineEdit, &QLineEdit::setEnabled);
}
SeerCatchpointCreateDialog::~SeerCatchpointCreateDialog () {
}
void SeerCatchpointCreateDialog::setFilename (const QString& text) {
filenameLineEdit->setText(text);
}
void SeerCatchpointCreateDialog::setFunctionName (const QString& text) {
functionLineEdit->setText(text);
}
void SeerCatchpointCreateDialog::setLabelName (const QString& text) {
labelLineEdit->setText(text);
}
void SeerCatchpointCreateDialog::setLineNumber (const QString& text) {
lineNumberLineEdit->setText(text);
}
QString SeerCatchpointCreateDialog::filenameText () const {
return filenameLineEdit->text();
}
QString SeerCatchpointCreateDialog::functionNameText () const {
return functionLineEdit->text();
}
QString SeerCatchpointCreateDialog::labelNameText () const {
return labelLineEdit->text();
}
QString SeerCatchpointCreateDialog::lineNumberText () const {
return lineNumberLineEdit->text();
}
void SeerCatchpointCreateDialog::setTemporaryEnabled (bool flag) {
temporaryCheckBox->setChecked(flag);
}
void SeerCatchpointCreateDialog::setHardwareEnabled (bool flag) {
hardwareCheckBox->setChecked(flag);
}
void SeerCatchpointCreateDialog::setPendingEnabled (bool flag) {
pendingCheckBox->setChecked(flag);
}
void SeerCatchpointCreateDialog::setDisabledEnabled (bool flag) {
disabledCheckBox->setChecked(flag);
}
void SeerCatchpointCreateDialog::setConditionalEnabled (bool flag) {
conditionalCheckBox->setChecked(flag);
conditionalLineEdit->setEnabled(flag);
}
void SeerCatchpointCreateDialog::setIgnoreCountEnabled (bool flag) {
ignoreCountCheckBox->setChecked(flag);
ignoreCountLineEdit->setEnabled(flag);
}
void SeerCatchpointCreateDialog::setThreadIdEnabled (bool flag) {
threadIdCheckBox->setChecked(flag);
threadIdLineEdit->setEnabled(flag);
}
void SeerCatchpointCreateDialog::setConditionalText (const QString& text) {
conditionalLineEdit->setText(text);
}
void SeerCatchpointCreateDialog::setIgnoreCountText (const QString& text) {
ignoreCountLineEdit->setText(text);
}
void SeerCatchpointCreateDialog::setThreadIdText (const QString& text) {
threadIdLineEdit->setText(text);
}
bool SeerCatchpointCreateDialog::temporaryEnabled () const {
return temporaryCheckBox->isChecked();
}
bool SeerCatchpointCreateDialog::hardwareEnabled () const {
return hardwareCheckBox->isChecked();
}
bool SeerCatchpointCreateDialog::pendingEnabled () const {
return pendingCheckBox->isChecked();
}
bool SeerCatchpointCreateDialog::disabledEnabled () const {
return disabledCheckBox->isChecked();
}
bool SeerCatchpointCreateDialog::conditionalEnabled () const {
return conditionalCheckBox->isChecked();
}
bool SeerCatchpointCreateDialog::ignoreCountEnabled () const {
return ignoreCountCheckBox->isChecked();
}
bool SeerCatchpointCreateDialog::threadIdEnabled () const {
return threadIdCheckBox->isChecked();
}
QString SeerCatchpointCreateDialog::conditionalText () const {
return conditionalLineEdit->text();
}
QString SeerCatchpointCreateDialog::ignoreCountText () const {
return ignoreCountLineEdit->text();
}
QString SeerCatchpointCreateDialog::threadIdText () const {
return threadIdLineEdit->text();
}
QString SeerCatchpointCreateDialog::catchpointText () const {
// Build a catchpoint specification.
QString catchpointParameters;
if (temporaryEnabled()) {
catchpointParameters += " -t";
}
if (hardwareEnabled()) {
catchpointParameters += " -h";
}
if (pendingEnabled()) {
catchpointParameters += " -f";
}
if (disabledEnabled()) {
catchpointParameters += " -d";
}
if (conditionalEnabled()) {
if (conditionalText() != "") {
catchpointParameters += " -c " + conditionalText();
}
}
if (ignoreCountEnabled()) {
if (ignoreCountText() != "") {
catchpointParameters += " -i " + ignoreCountText();
}
}
if (threadIdEnabled()) {
if (threadIdText() != "") {
catchpointParameters += " -p " + threadIdText();
}
}
if (filenameText() != "") {
catchpointParameters += " --source " + filenameText();
}
if (functionNameText() != "") {
catchpointParameters += " --function " + functionNameText();
}
if (labelNameText() != "") {
catchpointParameters += " --label " + labelNameText();
}
if (lineNumberText() != "") {
catchpointParameters += " --line " + lineNumberText();
}
return catchpointParameters;
}
+56
View File
@@ -0,0 +1,56 @@
#pragma once
#include <QtWidgets/QDialog>
#include <QtCore/QString>
#include "ui_SeerCatchpointCreateDialog.h"
class SeerCatchpointCreateDialog : public QDialog, protected Ui::SeerCatchpointCreateDialogForm {
Q_OBJECT
public:
explicit SeerCatchpointCreateDialog (QWidget* parent = 0);
~SeerCatchpointCreateDialog ();
void setFilename (const QString& text);
void setFunctionName (const QString& text);
void setLabelName (const QString& text);
void setLineNumber (const QString& text);
QString filenameText () const;
QString functionNameText () const;
QString labelNameText () const;
QString lineNumberText () const;
void setTemporaryEnabled (bool flag);
void setHardwareEnabled (bool flag);
void setPendingEnabled (bool flag);
void setDisabledEnabled (bool flag);
void setConditionalEnabled (bool flag);
void setIgnoreCountEnabled (bool flag);
void setThreadIdEnabled (bool flag);
void setConditionalText (const QString& text);
void setIgnoreCountText (const QString& text);
void setThreadIdText (const QString& text);
bool temporaryEnabled () const;
bool hardwareEnabled () const;
bool pendingEnabled () const;
bool disabledEnabled () const;
bool conditionalEnabled () const;
bool ignoreCountEnabled () const;
bool threadIdEnabled () const;
QString conditionalText () const;
QString ignoreCountText () const;
QString threadIdText () const;
QString catchpointText () const;
public slots:
private:
};
+286
View File
@@ -0,0 +1,286 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SeerCatchpointCreateDialogForm</class>
<widget class="QDialog" name="SeerCatchpointCreateDialogForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>489</width>
<height>395</height>
</rect>
</property>
<property name="windowTitle">
<string>Create a Catchpoint</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="catchpointLocationGroupBox">
<property name="title">
<string>Catchpoint Location</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="filenameLabel">
<property name="text">
<string>Filename</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="filenameLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lineNumberLabel">
<property name="text">
<string>Line number</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineNumberLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="lineNumberHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="functionLabel">
<property name="text">
<string>Function</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="functionLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelLabel">
<property name="text">
<string>Label</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="labelLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="labelHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="catchpointTypeGroupBox">
<property name="title">
<string>Catchpoint Type</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="temporaryCheckBox">
<property name="text">
<string>Temporary</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="temporaryHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="conditionalCheckBox">
<property name="text">
<string>Conditional</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="conditionalLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="hardwareCheckBox">
<property name="text">
<string>Hardware</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="hardwareHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="ignoreCountCheckBox">
<property name="text">
<string>Ignore Count</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="ignoreCountLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="pendingCheckBox">
<property name="text">
<string>Pending</string>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="pendingHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="threadIdCheckBox">
<property name="text">
<string>Thread Id</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="threadIdLineEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="disabledCheckBox">
<property name="text">
<string>Disabled</string>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="disabledHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SeerCatchpointCreateDialogForm</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SeerCatchpointCreateDialogForm</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+435
View File
@@ -0,0 +1,435 @@
#include "SeerWatchpointsBrowserWidget.h"
#include "SeerWatchpointCreateDialog.h"
#include "SeerUtl.h"
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItemIterator>
#include <QtWidgets/QApplication>
#include <QtCore/QDebug>
SeerWatchpointsBrowserWidget::SeerWatchpointsBrowserWidget (QWidget* parent) : QWidget(parent) {
// Construct the UI.
setupUi(this);
// Setup the widgets
watchpointsTreeWidget->clear();
watchpointsTreeWidget->setSortingEnabled(false);
watchpointsTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
watchpointsTreeWidget->resizeColumnToContents(0); // number
watchpointsTreeWidget->resizeColumnToContents(1); // type
watchpointsTreeWidget->resizeColumnToContents(2); // disp
watchpointsTreeWidget->resizeColumnToContents(3); // enabled
watchpointsTreeWidget->resizeColumnToContents(4); // addr
//watchpointsTreeWidget->resizeColumnToContents(5); // func Too long to show
watchpointsTreeWidget->resizeColumnToContents(6); // file
//watchpointsTreeWidget->resizeColumnToContents(7); // fullname Too long to show
watchpointsTreeWidget->resizeColumnToContents(8); // line
watchpointsTreeWidget->resizeColumnToContents(9); // thread-groups
watchpointsTreeWidget->resizeColumnToContents(10); // times
watchpointsTreeWidget->resizeColumnToContents(11); // original-location / expression
watchpointsTreeWidget->resizeColumnToContents(12); // value
watchpointsTreeWidget->resizeColumnToContents(13); // new value
watchpointsTreeWidget->resizeColumnToContents(14); // used
watchpointsTreeWidget->setColumnHidden(4, true); // Hide the 'addr' column.
watchpointsTreeWidget->setColumnHidden(5, true); // Hide the 'func' column.
watchpointsTreeWidget->setColumnHidden(14, true); // Hide the 'used' column.
watchpointsTreeWidget->clear();
// Connect things.
QObject::connect(watchpointsTreeWidget, &QTreeWidget::itemDoubleClicked, this, &SeerWatchpointsBrowserWidget::handleItemDoubleClicked);
QObject::connect(refreshWatchpointsToolButton, &QToolButton::clicked, this, &SeerWatchpointsBrowserWidget::handleRefreshToolButton);
QObject::connect(addWatchpointToolButton, &QToolButton::clicked, this, &SeerWatchpointsBrowserWidget::handleAddToolButton);
QObject::connect(deleteWatchpointsToolButton, &QToolButton::clicked, this, &SeerWatchpointsBrowserWidget::handleDeleteToolButton);
QObject::connect(enableWatchpointsToolButton, &QToolButton::clicked, this, &SeerWatchpointsBrowserWidget::handleEnableToolButton);
QObject::connect(disableWatchpointsToolButton, &QToolButton::clicked, this, &SeerWatchpointsBrowserWidget::handleDisableToolButton);
}
SeerWatchpointsBrowserWidget::~SeerWatchpointsBrowserWidget () {
}
void SeerWatchpointsBrowserWidget::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,BreakpointTable={") && text.endsWith("}")) {
//
// ^done,BreakpointTable={
// nr_rows="2",nr_cols="6",
//
// hdr=[
// {width="7",alignment="-1",col_name="number",colhdr="Num"},
// {width="14",alignment="-1",col_name="type",colhdr="Type"},
// {width="4",alignment="-1",col_name="disp",colhdr="Disp"},
// {width="3",alignment="-1",col_name="enabled",colhdr="Enb"},
// {width="18",alignment="-1",col_name="addr",colhdr="Address"},
// {width="40",alignment="2",col_name="what",colhdr="What"}
// ],
//
// body=[
// bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x0000000000400c17",func="main(int, char**)",file="helloworld.cpp",fullname="/home/erniep/Development/Peak/src/Seer/helloworld/helloworld.cpp",line="8",thread-groups=["i1"],times="0",original-location="main"},
// bkpt={number="3",
// type="breakpoint",
// disp="keep",
// enabled="y",
// addr="0x0000000000400d72",
// func="function1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)",
// file="function1.cpp",
// fullname="/home/erniep/Development/Peak/src/Seer/helloworld/function1.cpp",
// line="7",
// thread-groups=["i1"],
// times="0",
// original-location="function1"}
// ]
// }
//
QString newtext = Seer::filterEscapes(text); // Filter escaped characters.
QString body_text = Seer::parseFirst(newtext, "body=", '[', ']', false);
//qDebug() << __PRETTY_FUNCTION__ << ":" << body_text;
// No rows? Just clear the tree.
if (body_text == "") {
watchpointsTreeWidget->clear();
// Otherwise, populate it.
}else{
// Mark each entry initially as "unused".
// Later, some will be marked as "reused" or "new". Then the "unused" ones will
// be deleted.
QTreeWidgetItemIterator it(watchpointsTreeWidget);
while (*it) {
(*it)->setText(14, "unused");
++it;
}
QStringList bkpt_list = Seer::parse(newtext, "bkpt=", '{', '}', false);
for ( const auto& bkpt_text : bkpt_list ) {
QString number_text = Seer::parseFirst(bkpt_text, "number=", '"', '"', false);
QString type_text = Seer::parseFirst(bkpt_text, "type=", '"', '"', false);
QString disp_text = Seer::parseFirst(bkpt_text, "disp=", '"', '"', false);
QString enabled_text = Seer::parseFirst(bkpt_text, "enabled=", '"', '"', false);
QString addr_text = Seer::parseFirst(bkpt_text, "addr=", '"', '"', false);
QString func_text = Seer::parseFirst(bkpt_text, "func=", '"', '"', false);
QString file_text = Seer::parseFirst(bkpt_text, "file=", '"', '"', false);
QString fullname_text = Seer::parseFirst(bkpt_text, "fullname=", '"', '"', false);
QString line_text = Seer::parseFirst(bkpt_text, "line=", '"', '"', false);
QString thread_groups_text = Seer::parseFirst(bkpt_text, "thread-groups=", '[', ']', false);
QString times_text = Seer::parseFirst(bkpt_text, "times=", '"', '"', false);
QString original_location_text = Seer::parseFirst(bkpt_text, "original-location=", '"', '"', false);
// Only look for 'watchpoint' type break points.
if (type_text != "hw watchpoint" && type_text != "watchpoint" && type_text != "read watchpoint" && type_text != "acc watchpoint") {
continue;
}
// Instead of creating a new tree each time, we will reuse existing items, if they are there.
// This allows the expanded items to remain expanded.
QList<QTreeWidgetItem*> matches = watchpointsTreeWidget->findItems(number_text, Qt::MatchExactly, 0);
// No matches. So can't reuse. Add the new entry.
if (matches.size() == 0) {
// Add the level to the tree.
QTreeWidgetItem* topItem = new QTreeWidgetItem;
topItem->setText(0, number_text);
topItem->setText(1, type_text);
topItem->setText(2, disp_text);
topItem->setText(3, enabled_text);
topItem->setText(4, addr_text);
topItem->setText(5, func_text);
topItem->setText(6, file_text);
topItem->setText(7, fullname_text);
topItem->setText(8, line_text);
topItem->setText(9, thread_groups_text);
topItem->setText(10, times_text);
topItem->setText(11, original_location_text);
topItem->setText(12, "");
topItem->setText(13, "");
topItem->setText(14, "new");
watchpointsTreeWidget->addTopLevelItem(topItem);
// Found a match. Reuse it.
// But don't overwrite the file, fullname, line, value, and new value.
}else{
QTreeWidgetItem* topItem = matches.takeFirst();
topItem->setText(0, number_text);
topItem->setText(1, type_text);
topItem->setText(2, disp_text);
topItem->setText(3, enabled_text);
topItem->setText(4, addr_text);
topItem->setText(5, func_text);
//topItem->setText(6, file_text);
//topItem->setText(7, fullname_text);
//topItem->setText(8, line_text);
topItem->setText(9, thread_groups_text);
topItem->setText(10, times_text);
topItem->setText(11, original_location_text);
//topItem->setText(12, "");
//topItem->setText(13, "");
topItem->setText(14, "reused");
}
}
// At this point, there are some new entries, some reused entries, and some unused ones.
// Delete the unused ones. They are obsolete.
QList<QTreeWidgetItem*> matches = watchpointsTreeWidget->findItems("unused", Qt::MatchExactly, 14);
qDeleteAll(matches);
}
}else if (text.startsWith("*stopped,reason=\"") || text.startsWith("*stopped,hw-awpt={")) {
QString reason_text = Seer::parseFirst(text, "reason=", '"', '"', false);
if (reason_text == "watchpoint-trigger") {
//*stopped,reason="watchpoint-trigger",wpt={number="3",exp="i"},value={old="32767",new="42"},frame={addr="0x0000000000400d79",func="function1",args=[{name="text",value="\"Hello, World!\""}],file="function1.cpp",fullname="/home/erniep/Development/Peak/src/Seer/helloworld/function1.cpp",line="9",arch="i386:x86-64"},thread-id="1",stopped-threads="all",core="0"
QString wpt_text = Seer::parseFirst(text, "wpt=", '{', '}', false);
QString number_text = Seer::parseFirst(wpt_text, "number=", '"', '"', false);
QString exp_text = Seer::parseFirst(wpt_text, "exp=", '"', '"', false);
QString value_text = Seer::parseFirst(text, "value=", '{', '}', false);
QString old_text = Seer::parseFirst(value_text, "old=", '"', '"', false);
QString new_text = Seer::parseFirst(value_text, "new=", '"', '"', false);
QString frame_text = Seer::parseFirst(text, "frame=", '{', '}', false);
QString file_text = Seer::parseFirst(frame_text, "file=", '"', '"', false);
QString fullname_text = Seer::parseFirst(frame_text, "fullname=", '"', '"', false);
QString line_text = Seer::parseFirst(frame_text, "line=", '"', '"', false);
// Find watchpoint number in the tree
QList<QTreeWidgetItem*> matches = watchpointsTreeWidget->findItems(number_text, Qt::MatchExactly, 0);
if (matches.size() > 0) {
//qDebug() << __PRETTY_FUNCTION__ << ":" << text;
QTreeWidgetItem* item = matches.first();
item->setText(6, file_text);
item->setText(7, fullname_text);
item->setText(8, line_text);
item->setText(12, old_text);
item->setText(13, new_text);
}
}else if (reason_text == "read-watchpoint-trigger") {
//*stopped,reason="read-watchpoint-trigger",hw-rwpt={number="5",exp="i"},value={value="42"},frame={addr="0x0000000000400d9a",func="function1",args=[{name="text",value="\"Hello, World!\""}],file="function1.cpp",fullname="/home/erniep/Development/Peak/src/Seer/helloworld/function1.cpp",line="11",arch="i386:x86-64"},thread-id="1",stopped-threads="all",core="4"
QString hwwpt_text = Seer::parseFirst(text, "hw-rwpt=", '{', '}', false);
QString number_text = Seer::parseFirst(hwwpt_text, "number=", '"', '"', false);
QString exp_text = Seer::parseFirst(hwwpt_text, "exp=", '"', '"', false);
QString value_text = Seer::parseFirst(text, "value=", '{', '}', false);
QString value_text2 = Seer::parseFirst(value_text, "value=", '"', '"', false);
QString frame_text = Seer::parseFirst(text, "frame=", '{', '}', false);
QString file_text = Seer::parseFirst(frame_text, "file=", '"', '"', false);
QString fullname_text = Seer::parseFirst(frame_text, "fullname=", '"', '"', false);
QString line_text = Seer::parseFirst(frame_text, "line=", '"', '"', false);
// Find watchpoint number in the tree
QList<QTreeWidgetItem*> matches = watchpointsTreeWidget->findItems(number_text, Qt::MatchExactly, 0);
if (matches.size() > 0) {
//qDebug() << __PRETTY_FUNCTION__ << ":" << text;
QTreeWidgetItem* item = matches.first();
item->setText(6, file_text);
item->setText(7, fullname_text);
item->setText(8, line_text);
item->setText(12, value_text2);
item->setText(13, "");
}
}else if (reason_text == "access-watchpoint-trigger") {
//*stopped,reason="access-watchpoint-trigger",hw-awpt={number="3",exp="v"},value={old="1",new="11"},frame={addr="0x000000000040059a",func="bar",args=[{name="v",value="11"}],file="helloonefile.cpp",fullname="/home/erniep/Development/Peak/src/Seer/helloonefile/helloonefile.cpp",line="15",arch="i386:x86-64"},thread-id="1",stopped-threads="all",core="3"
QString hwawpt_text = Seer::parseFirst(text, "hw-awpt=", '{', '}', false);
QString number_text = Seer::parseFirst(hwawpt_text, "number=", '"', '"', false);
QString exp_text = Seer::parseFirst(hwawpt_text, "exp=", '"', '"', false);
QString value_text = Seer::parseFirst(text, "value=", '{', '}', false);
QString old_text = Seer::parseFirst(value_text, "old=", '"', '"', false);
QString new_text = Seer::parseFirst(value_text, "new=", '"', '"', false);
QString frame_text = Seer::parseFirst(text, "frame=", '{', '}', false);
QString file_text = Seer::parseFirst(frame_text, "file=", '"', '"', false);
QString fullname_text = Seer::parseFirst(frame_text, "fullname=", '"', '"', false);
QString line_text = Seer::parseFirst(frame_text, "line=", '"', '"', false);
// Find watchpoint number in the tree
QList<QTreeWidgetItem*> matches = watchpointsTreeWidget->findItems(number_text, Qt::MatchExactly, 0);
if (matches.size() > 0) {
//qDebug() << __PRETTY_FUNCTION__ << ":" << text;
QTreeWidgetItem* item = matches.first();
item->setText(6, file_text);
item->setText(7, fullname_text);
item->setText(8, line_text);
item->setText(12, old_text);
item->setText(13, new_text);
}
}
}else if (text.startsWith("^error,msg=\"No registers.\"")) {
// Ignore.
}else{
// Ignore others.
}
watchpointsTreeWidget->resizeColumnToContents(0);
watchpointsTreeWidget->resizeColumnToContents(1);
watchpointsTreeWidget->resizeColumnToContents(2);
watchpointsTreeWidget->resizeColumnToContents(3);
watchpointsTreeWidget->resizeColumnToContents(4);
//watchpointsTreeWidget->resizeColumnToContents(5);
watchpointsTreeWidget->resizeColumnToContents(6);
//watchpointsTreeWidget->resizeColumnToContents(7);
watchpointsTreeWidget->resizeColumnToContents(8);
watchpointsTreeWidget->resizeColumnToContents(9);
watchpointsTreeWidget->resizeColumnToContents(10);
watchpointsTreeWidget->resizeColumnToContents(11);
watchpointsTreeWidget->resizeColumnToContents(12);
watchpointsTreeWidget->resizeColumnToContents(13);
watchpointsTreeWidget->resizeColumnToContents(14);
QApplication::restoreOverrideCursor();
}
void SeerWatchpointsBrowserWidget::handleStoppingPointReached () {
// Don't do any work if the widget is hidden.
if (isHidden()) {
return;
}
emit refreshWatchpointsList();
}
void SeerWatchpointsBrowserWidget::handleItemDoubleClicked (QTreeWidgetItem* item, int column) {
Q_UNUSED(column);
int lineno = item->text(8).toInt();
emit selectedFile(item->text(6), item->text(7), lineno);
}
void SeerWatchpointsBrowserWidget::handleRefreshToolButton () {
emit refreshWatchpointsList();
}
void SeerWatchpointsBrowserWidget::handleAddToolButton () {
SeerWatchpointCreateDialog dlg(this);
int ret = dlg.exec();
if (ret == 0) {
return;
}
// Build a watchpoint specification.
QString watchpointParameters = dlg.watchpointText();
// If nothing, just return.
if (watchpointParameters == "") {
return;
}
// Otherwise send the command to create the watchpoint.
emit insertWatchpoint(watchpointParameters);
}
void SeerWatchpointsBrowserWidget::handleDeleteToolButton () {
// Get selected tree items.
QList<QTreeWidgetItem*> items = watchpointsTreeWidget->selectedItems();
// Build a string that is a list of watchpoints.
QString watchpoints;
QList<QTreeWidgetItem*>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
if (i != items.begin()) {
watchpoints += " ";
}
watchpoints += (*i)->text(0);
}
// Don't do anything if the list of watchpoints is empty.
if (watchpoints == "") {
return;
}
// Send the signal.
emit deleteWatchpoints(watchpoints);
}
void SeerWatchpointsBrowserWidget::handleEnableToolButton () {
// Get selected tree items.
QList<QTreeWidgetItem*> items = watchpointsTreeWidget->selectedItems();
// Build a string that is a list of watchpoints.
QString watchpoints;
QList<QTreeWidgetItem*>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
if (i != items.begin()) {
watchpoints += " ";
}
watchpoints += (*i)->text(0);
}
// Don't do anything if the list of watchpoints is empty.
if (watchpoints == "") {
return;
}
// Send the signal.
emit enableWatchpoints(watchpoints);
}
void SeerWatchpointsBrowserWidget::handleDisableToolButton () {
// Get selected tree items.
QList<QTreeWidgetItem*> items = watchpointsTreeWidget->selectedItems();
// Build a string that is a list of watchpoints.
QString watchpoints;
QList<QTreeWidgetItem*>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
if (i != items.begin()) {
watchpoints += " ";
}
watchpoints += (*i)->text(0);
}
// Don't do anything if the list of watchpoints is empty.
if (watchpoints == "") {
return;
}
// Send the signal.
emit disableWatchpoints(watchpoints);
}
void SeerWatchpointsBrowserWidget::showEvent (QShowEvent* event) {
QWidget::showEvent(event);
emit refreshWatchpointsList();
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <QtWidgets/QWidget>
#include <QtCore/QString>
#include "ui_SeerWatchpointsBrowserWidget.h"
class SeerWatchpointsBrowserWidget : public QWidget, protected Ui::SeerWatchpointsBrowserWidgetForm {
Q_OBJECT
public:
explicit SeerWatchpointsBrowserWidget (QWidget* parent = 0);
~SeerWatchpointsBrowserWidget ();
public slots:
void handleText (const QString& text);
void handleStoppingPointReached ();
private slots:
void handleItemDoubleClicked (QTreeWidgetItem* item, int column);
void handleRefreshToolButton ();
void handleAddToolButton ();
void handleDeleteToolButton ();
void handleEnableToolButton ();
void handleDisableToolButton ();
signals:
void refreshWatchpointsList ();
void deleteWatchpoints (QString watchpoints);
void enableWatchpoints (QString watchpoints);
void disableWatchpoints (QString watchpoints);
void insertWatchpoint (QString watchpoint);
void selectedFile (QString file, QString fullname, int lineno);
protected:
void showEvent (QShowEvent* event);
private:
};
+190
View File
@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SeerWatchpointsBrowserWidgetForm</class>
<widget class="QWidget" name="SeerWatchpointsBrowserWidgetForm">
<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">
<widget class="QTreeWidget" name="watchpointsTreeWidget">
<property name="columnCount">
<number>15</number>
</property>
<column>
<property name="text">
<string>Number</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Disposition</string>
</property>
</column>
<column>
<property name="text">
<string>Enabled</string>
</property>
</column>
<column>
<property name="text">
<string>Address</string>
</property>
</column>
<column>
<property name="text">
<string>Function</string>
</property>
</column>
<column>
<property name="text">
<string>File</string>
</property>
</column>
<column>
<property name="text">
<string>Fullname</string>
</property>
</column>
<column>
<property name="text">
<string>Line</string>
</property>
</column>
<column>
<property name="text">
<string>Thread Groups</string>
</property>
</column>
<column>
<property name="text">
<string>Times</string>
</property>
</column>
<column>
<property name="text">
<string>Expression</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
<column>
<property name="text">
<string>New Value</string>
</property>
</column>
<column>
<property name="text">
<string>Used</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QToolButton" name="refreshWatchpointsToolButton">
<property name="toolTip">
<string>Refresh the list of watchpoints.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="view-refresh">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="addWatchpointToolButton">
<property name="toolTip">
<string>Add a new watchpoint.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="document-new">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="deleteWatchpointsToolButton">
<property name="toolTip">
<string>Delete selected watchpoints.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="edit-delete">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="enableWatchpointsToolButton">
<property name="toolTip">
<string>Enable selected watchpoints.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="list-add">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="disableWatchpointsToolButton">
<property name="toolTip">
<string>Disable selected watchpoints.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="list-remove">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>