Commit 2074ce8f authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger[New CDB]: Add more fine-grained settings for events/break.

Add options to break on Cpp Exceptions, thread creation, etc.
parent 5df88137
......@@ -520,6 +520,8 @@ void CdbEngine::runEngine()
{
if (debug)
qDebug("runEngine");
foreach (const QString &breakEvent, m_options->breakEvents)
postCommand(QByteArray("sxe ") + breakEvent.toAscii(), 0);
postCommand("g", 0);
}
......
......@@ -44,6 +44,7 @@ static const char enabledKeyC[] = "Enabled";
static const char pathKeyC[] = "Path";
static const char symbolPathsKeyC[] = "SymbolPaths";
static const char sourcePathsKeyC[] = "SourcePaths";
static const char breakEventKeyC[] = "BreakEvent";
static const char is64bitKeyC[] = "64bit";
namespace Debugger {
......@@ -145,6 +146,7 @@ void CdbOptions::fromSettings(QSettings *s)
executable = s->value(keyRoot + QLatin1String(pathKeyC), executable).toString();
symbolPaths = s->value(keyRoot + QLatin1String(symbolPathsKeyC), QStringList()).toStringList();
sourcePaths = s->value(keyRoot + QLatin1String(sourcePathsKeyC), QStringList()).toStringList();
breakEvents = s->value(keyRoot + QLatin1String(breakEventKeyC), QStringList()).toStringList();
}
void CdbOptions::toSettings(QSettings *s) const
......@@ -155,6 +157,7 @@ void CdbOptions::toSettings(QSettings *s) const
s->setValue(QLatin1String(is64bitKeyC), is64bit);
s->setValue(QLatin1String(symbolPathsKeyC), symbolPaths);
s->setValue(QLatin1String(sourcePathsKeyC), sourcePaths);
s->setValue(QLatin1String(breakEventKeyC), breakEvents);
s->endGroup();
}
......@@ -163,7 +166,8 @@ bool CdbOptions::equals(const CdbOptions &rhs) const
return enabled == rhs.enabled && is64bit == rhs.is64bit
&& executable == rhs.executable
&& symbolPaths == rhs.symbolPaths
&& sourcePaths == rhs.sourcePaths;
&& sourcePaths == rhs.sourcePaths
&& breakEvents == rhs.breakEvents;
}
bool CdbOptions::autoDetectExecutable(QString *outPath, bool *is64bitIn /* = 0 */,
......
......@@ -63,6 +63,8 @@ public:
QString executable;
QStringList symbolPaths;
QStringList sourcePaths;
// Events to break on (Command 'sxe' with abbreviation and optional parameter)
QStringList breakEvents;
};
inline bool operator==(const CdbOptions &s1, const CdbOptions &s2)
......
......@@ -48,6 +48,7 @@
#include <QtCore/QTimer>
#include <QtCore/QProcess>
#include <QtGui/QMessageBox>
#include <QtGui/QLineEdit>
#include <QtGui/QDesktopServices>
static const char *dgbToolsDownloadLink32C = "http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx";
......@@ -56,6 +57,118 @@ static const char *dgbToolsDownloadLink64C = "http://www.microsoft.com/whdc/devt
namespace Debugger {
namespace Cdb {
struct EventsDescription {
const char *abbreviation;
bool hasParameter;
const char *description;
};
// Parameters of the "sxe" command
const EventsDescription eventDescriptions[] =
{
{"eh", false, QT_TRANSLATE_NOOP("Debugger::Cdb::CdbBreakEventWidget",
"C++ exception")},
{"ct", false, QT_TRANSLATE_NOOP("Debugger::Cdb::CdbBreakEventWidget",
"Thread creation")},
{"et", false, QT_TRANSLATE_NOOP("Debugger::Cdb::CdbBreakEventWidget",
"Thread exit")},
{"ld", true, QT_TRANSLATE_NOOP("Debugger::Cdb::CdbBreakEventWidget",
"Load Module:")},
{"ud", true, QT_TRANSLATE_NOOP("Debugger::Cdb::CdbBreakEventWidget",
"Unload Module:")},
{"out", true, QT_TRANSLATE_NOOP("Debugger::Cdb::CdbBreakEventWidget",
"Output:")}
};
static inline int indexOfEvent(const QString &abbrev)
{
const size_t eventCount = sizeof(eventDescriptions) / sizeof(EventsDescription);
for (size_t e = 0; e < eventCount; e++)
if (abbrev == QLatin1String(eventDescriptions[e].abbreviation))
return int(e);
return -1;
}
CdbBreakEventWidget::CdbBreakEventWidget(QWidget *parent) : QWidget(parent)
{
// 1 column with checkboxes only,
// further columns with checkbox + parameter
QHBoxLayout *mainLayout = new QHBoxLayout;
QVBoxLayout *leftLayout = new QVBoxLayout;
QFormLayout *parameterLayout = 0;
mainLayout->addLayout(leftLayout);
const size_t eventCount = sizeof(eventDescriptions) / sizeof(EventsDescription);
for (size_t e = 0; e < eventCount; e++) {
QCheckBox *cb = new QCheckBox(tr(eventDescriptions[e].description));
QLineEdit *le = 0;
if (eventDescriptions[e].hasParameter) {
if (!parameterLayout) {
parameterLayout = new QFormLayout;
mainLayout->addSpacerItem(new QSpacerItem(20, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
mainLayout->addLayout(parameterLayout);
}
le = new QLineEdit;
parameterLayout->addRow(cb, le);
if (parameterLayout->count() >= 4) // New column
parameterLayout = 0;
} else {
leftLayout->addWidget(cb);
}
m_checkBoxes.push_back(cb);
m_lineEdits.push_back(le);
}
setLayout(mainLayout);
}
void CdbBreakEventWidget::clear()
{
foreach (QLineEdit *l, m_lineEdits) {
if (l)
l->clear();
}
foreach (QCheckBox *c, m_checkBoxes)
c->setChecked(false);
}
void CdbBreakEventWidget::setBreakEvents(const QStringList &l)
{
clear();
// Split the list of ("eh", "out:MyOutput")
foreach (const QString &evt, l) {
const int colonPos = evt.indexOf(QLatin1Char(':'));
const QString abbrev = colonPos != -1 ? evt.mid(0, colonPos) : evt;
const int index = indexOfEvent(abbrev);
if (index != -1)
m_checkBoxes.at(index)->setChecked(true);
if (colonPos != -1 && m_lineEdits.at(index))
m_lineEdits.at(index)->setText(evt.mid(colonPos + 1));
}
}
QString CdbBreakEventWidget::filterText(int i) const
{
return m_lineEdits.at(i) ? m_lineEdits.at(i)->text() : QString();
}
QStringList CdbBreakEventWidget::breakEvents() const
{
// Compile a list of ("eh", "out:MyOutput")
QStringList rc;
const int eventCount = sizeof(eventDescriptions) / sizeof(EventsDescription);
for (int e = 0; e < eventCount; e++) {
if (m_checkBoxes.at(e)->isChecked()) {
const QString filter = filterText(e);
QString s = QLatin1String(eventDescriptions[e].abbreviation);
if (!filter.isEmpty()) {
s += QLatin1Char(':');
s += filter;
}
rc.push_back(s);
}
}
return rc;
}
static inline QString msgPathConfigNote()
{
#ifdef Q_OS_WIN
......@@ -74,7 +187,8 @@ static inline QString msgPathConfigNote()
}
CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
QWidget(parent), m_reportTimer(0)
QWidget(parent), m_breakEventWidget(new CdbBreakEventWidget),
m_reportTimer(0)
{
m_ui.setupUi(this);
m_ui.noteLabel->setText(msgPathConfigNote());
......@@ -84,6 +198,9 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
m_ui.pathChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_ui.pathChooser->addButton(tr("Autodetect"), this, SLOT(autoDetect()));
m_ui.cdbPathGroupBox->installEventFilter(this);
QVBoxLayout *eventLayout = new QVBoxLayout;
eventLayout->addWidget(m_breakEventWidget);
m_ui.eventGroupBox->setLayout(eventLayout);
}
void CdbOptionsPageWidget::setOptions(CdbOptions &o)
......@@ -93,6 +210,7 @@ void CdbOptionsPageWidget::setOptions(CdbOptions &o)
m_ui.cdbPathGroupBox->setChecked(o.enabled);
setSymbolPaths(o.symbolPaths);
m_ui.sourcePathListEditor->setPathList(o.sourcePaths);
m_breakEventWidget->setBreakEvents(o.breakEvents);
}
bool CdbOptionsPageWidget::is64Bit() const
......@@ -113,6 +231,7 @@ CdbOptions CdbOptionsPageWidget::options() const
rc.is64bit = is64Bit();
rc.symbolPaths = symbolPaths();
rc.sourcePaths = m_ui.sourcePathListEditor->pathList();
rc.breakEvents = m_breakEventWidget->breakEvents();
return rc;
}
......
......@@ -39,11 +39,33 @@
#include <QtCore/QPointer>
#include <QtCore/QSharedPointer>
QT_FORWARD_DECLARE_CLASS(QTimer)
QT_BEGIN_NAMESPACE
class QTimer;
QT_END_NAMESPACE
namespace Debugger {
namespace Cdb {
// Widget displaying a list of break events for the 'sxe' command
// with a checkbox to enable 'break' and optionally a QLineEdit for
// events with parameters (like 'out:Needle').
class CdbBreakEventWidget : public QWidget
{
Q_OBJECT
public:
explicit CdbBreakEventWidget(QWidget *parent = 0);
void setBreakEvents(const QStringList &l);
QStringList breakEvents() const;
private:
QString filterText(int i) const;
void clear();
QList<QCheckBox*> m_checkBoxes;
QList<QLineEdit*> m_lineEdits;
};
class CdbOptionsPageWidget : public QWidget
{
Q_OBJECT
......@@ -73,6 +95,7 @@ private:
QString *message);
Ui::CdbOptionsPageWidget2 m_ui;
CdbBreakEventWidget *m_breakEventWidget;
QTimer *m_reportTimer;
};
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>135</width>
<height>246</height>
<width>347</width>
<height>358</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
......@@ -83,6 +83,13 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="eventGroupBox">
<property name="title">
<string>Break on:</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment