Debugger: Add options page for cdb paths.

Change-Id: Iafb5fd88c101e716f538edc44113d21a880f2d3f
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
David Schulz
2013-05-22 00:49:51 -07:00
parent 5374a4f3cd
commit 92a15600a4
13 changed files with 242 additions and 336 deletions

View File

@@ -1,13 +1,11 @@
HEADERS += $$PWD/cdbengine.h \ HEADERS += $$PWD/cdbengine.h \
cdb/bytearrayinputstream.h \ cdb/bytearrayinputstream.h \
cdb/cdbparsehelpers.h \ cdb/cdbparsehelpers.h \
cdb/cdboptions.h \
cdb/cdboptionspage.h cdb/cdboptionspage.h
SOURCES += $$PWD/cdbengine.cpp \ SOURCES += $$PWD/cdbengine.cpp \
cdb/bytearrayinputstream.cpp \ cdb/bytearrayinputstream.cpp \
cdb/cdbparsehelpers.cpp \ cdb/cdbparsehelpers.cpp \
cdb/cdboptions.cpp \
cdb/cdboptionspage.cpp cdb/cdboptionspage.cpp
FORMS += cdb/cdboptionspagewidget.ui FORMS += cdb/cdboptionspagewidget.ui

View File

@@ -195,9 +195,9 @@ Q_DECLARE_METATYPE(Debugger::Internal::ConditionalBreakPointCookie)
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
static inline bool isCreatorConsole(const DebuggerStartParameters &sp, const CdbOptions &o) static inline bool isCreatorConsole(const DebuggerStartParameters &sp)
{ {
return !o.cdbConsole && sp.useTerminal return !debuggerCore()->boolSetting(UseCdbConsole) && sp.useTerminal
&& (sp.startMode == StartInternal || sp.startMode == StartExternal); && (sp.startMode == StartInternal || sp.startMode == StartExternal);
} }
@@ -316,35 +316,29 @@ static inline bool validMode(DebuggerStartMode sm)
DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp, QString *errorMessage) DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp, QString *errorMessage)
{ {
if (Utils::HostOsInfo::isWindowsHost()) { if (Utils::HostOsInfo::isWindowsHost()) {
CdbOptionsPage *op = CdbOptionsPage::instance(); if (validMode(sp.startMode))
if (!op || !validMode(sp.startMode)) { return new CdbEngine(sp);
*errorMessage = QLatin1String("Internal error: Invalid start parameters passed for thee CDB engine."); *errorMessage = QLatin1String("Internal error: Invalid start parameters passed for thee CDB engine.");
return 0; } else {
}
return new CdbEngine(sp, op->options());
}
*errorMessage = QString::fromLatin1("Unsupported debug mode"); *errorMessage = QString::fromLatin1("Unsupported debug mode");
}
return 0; return 0;
} }
void addCdbOptionPages(QList<Core::IOptionsPage *> *opts) void addCdbOptionPages(QList<Core::IOptionsPage *> *opts)
{ {
if (Utils::HostOsInfo::isWindowsHost()) if (Utils::HostOsInfo::isWindowsHost()) {
opts->push_back(new CdbOptionsPage); opts->push_back(new CdbOptionsPage);
opts->push_back(new CdbPathsPage);
}
} }
#define QT_CREATOR_CDB_EXT "qtcreatorcdbext" #define QT_CREATOR_CDB_EXT "qtcreatorcdbext"
static inline Utils::SavedAction *theAssemblerAction() CdbEngine::CdbEngine(const DebuggerStartParameters &sp) :
{
return debuggerCore()->action(OperateByInstruction);
}
CdbEngine::CdbEngine(const DebuggerStartParameters &sp, const OptionsPtr &options) :
DebuggerEngine(sp), DebuggerEngine(sp),
m_creatorExtPrefix("<qtcreatorcdbext>|"), m_creatorExtPrefix("<qtcreatorcdbext>|"),
m_tokenPrefix("<token>"), m_tokenPrefix("<token>"),
m_options(options),
m_effectiveStartMode(NoStartMode), m_effectiveStartMode(NoStartMode),
m_accessible(false), m_accessible(false),
m_specialStopMode(NoSpecialStop), m_specialStopMode(NoSpecialStop),
@@ -363,7 +357,8 @@ CdbEngine::CdbEngine(const DebuggerStartParameters &sp, const OptionsPtr &option
m_watchPointY(0), m_watchPointY(0),
m_ignoreCdbOutput(false) m_ignoreCdbOutput(false)
{ {
connect(theAssemblerAction(), SIGNAL(triggered(bool)), this, SLOT(operateByInstructionTriggered(bool))); connect(debuggerCore()->action(OperateByInstruction), SIGNAL(triggered(bool)),
this, SLOT(operateByInstructionTriggered(bool)));
setObjectName(QLatin1String("CdbEngine")); setObjectName(QLatin1String("CdbEngine"));
connect(&m_process, SIGNAL(finished(int)), this, SLOT(processFinished())); connect(&m_process, SIGNAL(finished(int)), this, SLOT(processFinished()));
@@ -380,7 +375,7 @@ void CdbEngine::init()
m_specialStopMode = NoSpecialStop; m_specialStopMode = NoSpecialStop;
m_nextCommandToken = 0; m_nextCommandToken = 0;
m_currentBuiltinCommandIndex = -1; m_currentBuiltinCommandIndex = -1;
m_operateByInstructionPending = theAssemblerAction()->isChecked(); m_operateByInstructionPending = debuggerCore()->action(OperateByInstruction)->isChecked();
m_operateByInstruction = true; // Default CDB setting m_operateByInstruction = true; // Default CDB setting
m_notifyEngineShutdownOnTermination = false; m_notifyEngineShutdownOnTermination = false;
m_hasDebuggee = false; m_hasDebuggee = false;
@@ -583,9 +578,9 @@ void CdbEngine::setupEngine()
if (debug) if (debug)
qDebug(">setupEngine"); qDebug(">setupEngine");
// Nag to add symbol server and cache // Nag to add symbol server and cache
if (CdbSymbolPathListEditor::promptToAddSymbolPaths(CdbOptions::settingsGroup(), QStringList symbolPaths = debuggerCore()->stringListSetting(CdbSymbolPaths);
&(m_options->symbolPaths))) if (CdbSymbolPathListEditor::promptToAddSymbolPaths(&symbolPaths))
m_options->toSettings(Core::ICore::settings()); debuggerCore()->action(CdbSymbolPaths)->setValue(symbolPaths);
init(); init();
if (!m_logTime.elapsed()) if (!m_logTime.elapsed())
@@ -596,7 +591,7 @@ void CdbEngine::setupEngine()
// console, too, but that immediately closes when the debuggee quits. // console, too, but that immediately closes when the debuggee quits.
// Use the Creator stub instead. // Use the Creator stub instead.
const DebuggerStartParameters &sp = startParameters(); const DebuggerStartParameters &sp = startParameters();
const bool launchConsole = isCreatorConsole(sp, *m_options); const bool launchConsole = isCreatorConsole(sp);
m_effectiveStartMode = launchConsole ? AttachExternal : sp.startMode; m_effectiveStartMode = launchConsole ? AttachExternal : sp.startMode;
const bool ok = launchConsole ? const bool ok = launchConsole ?
startConsole(startParameters(), &errorMessage) : startConsole(startParameters(), &errorMessage) :
@@ -668,14 +663,18 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa
<< QLatin1String(".idle_cmd ") + QString::fromLatin1(m_extensionCommandPrefixBA) + QLatin1String("idle"); << QLatin1String(".idle_cmd ") + QString::fromLatin1(m_extensionCommandPrefixBA) + QLatin1String("idle");
if (sp.useTerminal) // Separate console if (sp.useTerminal) // Separate console
arguments << QLatin1String("-2"); arguments << QLatin1String("-2");
if (m_options->ignoreFirstChanceAccessViolation) if (debuggerCore()->boolSetting(IgnoreFirstChanceAccessViolation))
arguments << QLatin1String("-x"); arguments << QLatin1String("-x");
if (!m_options->symbolPaths.isEmpty())
arguments << QLatin1String("-y") << m_options->symbolPaths.join(QString(QLatin1Char(';'))); const QStringList &symbolPaths = debuggerCore()->stringListSetting(CdbSymbolPaths);
if (!m_options->sourcePaths.isEmpty()) if (!symbolPaths.isEmpty())
arguments << QLatin1String("-srcpath") << m_options->sourcePaths.join(QString(QLatin1Char(';'))); arguments << QLatin1String("-y") << symbolPaths.join(QString(QLatin1Char(';')));
const QStringList &sourcePaths = debuggerCore()->stringListSetting(CdbSourcePaths);
if (!sourcePaths.isEmpty())
arguments << QLatin1String("-srcpath") << sourcePaths.join(QString(QLatin1Char(';')));
// Compile argument string preserving quotes // Compile argument string preserving quotes
QString nativeArguments = m_options->additionalArguments; QString nativeArguments = debuggerCore()->stringSetting(CdbAdditionalArguments);
switch (sp.startMode) { switch (sp.startMode) {
case StartInternal: case StartInternal:
case StartExternal: case StartExternal:
@@ -692,7 +691,7 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa
if (sp.startMode == AttachCrashedExternal) { if (sp.startMode == AttachCrashedExternal) {
arguments << QLatin1String("-e") << sp.crashParameter << QLatin1String("-g"); arguments << QLatin1String("-e") << sp.crashParameter << QLatin1String("-g");
} else { } else {
if (isCreatorConsole(startParameters(), *m_options)) if (isCreatorConsole(startParameters()))
arguments << QLatin1String("-pr") << QLatin1String("-pb"); arguments << QLatin1String("-pr") << QLatin1String("-pb");
} }
break; break;
@@ -808,25 +807,21 @@ void CdbEngine::runEngine()
{ {
if (debug) if (debug)
qDebug("runEngine"); qDebug("runEngine");
foreach (const QString &breakEvent, m_options->breakEvents)
const QStringList &breakEvents =
debuggerCore()->stringListSetting(CdbBreakEvents);
foreach (const QString &breakEvent, breakEvents)
postCommand(QByteArray("sxe ") + breakEvent.toLatin1(), 0); postCommand(QByteArray("sxe ") + breakEvent.toLatin1(), 0);
// Break functions: each function must be fully qualified, // Break functions: each function must be fully qualified,
// else the debugger will slow down considerably. // else the debugger will slow down considerably.
foreach (const QString &breakFunctionS, m_options->breakFunctions) { if (debuggerCore()->boolSetting(CdbBreakOnCrtDbgReport)) {
const QByteArray breakFunction = breakFunctionS.toLatin1();
if (breakFunction == CdbOptions::crtDbgReport) {
// CrtDbgReport(): Add MSVC runtime (debug, release)
// and stop at Wide character version as well
const QByteArray module = msvcRunTime(startParameters().toolChainAbi.osFlavor()); const QByteArray module = msvcRunTime(startParameters().toolChainAbi.osFlavor());
const QByteArray debugModule = module + 'D'; const QByteArray debugModule = module + 'D';
const QByteArray wideFunc = breakFunction + 'W'; const QByteArray wideFunc = CdbOptionsPage::crtDbgReport + 'W';
postCommand(breakAtFunctionCommand(breakFunction, module), 0); postCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module), 0);
postCommand(breakAtFunctionCommand(wideFunc, module), 0); postCommand(breakAtFunctionCommand(wideFunc, module), 0);
postCommand(breakAtFunctionCommand(breakFunction, debugModule), 0); postCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule), 0);
postCommand(breakAtFunctionCommand(wideFunc, debugModule), 0); postCommand(breakAtFunctionCommand(wideFunc, debugModule), 0);
} else {
postCommand(breakAtFunctionCommand(breakFunction), 0);
}
} }
if (debuggerCore()->boolSetting(BreakOnWarning)) { if (debuggerCore()->boolSetting(BreakOnWarning)) {
postCommand("bm /( QtCored4!qWarning", 0); // 'bm': All overloads. postCommand("bm /( QtCored4!qWarning", 0); // 'bm': All overloads.
@@ -2785,7 +2780,7 @@ void CdbEngine::attemptBreakpointSynchronization()
switch (handler->state(id)) { switch (handler->state(id)) {
case BreakpointInsertRequested: case BreakpointInsertRequested:
if (parameters.type == BreakpointByFileAndLine if (parameters.type == BreakpointByFileAndLine
&& m_options->breakpointCorrection) { && debuggerCore()->boolSetting(CdbBreakPointCorrection)) {
if (lineCorrection.isNull()) if (lineCorrection.isNull())
lineCorrection.reset(new BreakpointCorrectionContext(debuggerCore()->cppCodeModelSnapshot(), lineCorrection.reset(new BreakpointCorrectionContext(debuggerCore()->cppCodeModelSnapshot(),
CppTools::CppModelManagerInterface::instance()->workingCopy())); CppTools::CppModelManagerInterface::instance()->workingCopy()));

View File

@@ -47,7 +47,6 @@ namespace Internal {
class DisassemblerAgent; class DisassemblerAgent;
struct CdbBuiltinCommand; struct CdbBuiltinCommand;
struct CdbExtensionCommand; struct CdbExtensionCommand;
struct CdbOptions;
struct MemoryViewCookie; struct MemoryViewCookie;
class ByteArrayInputStream; class ByteArrayInputStream;
class GdbMi; class GdbMi;
@@ -57,8 +56,6 @@ class CdbEngine : public Debugger::DebuggerEngine
Q_OBJECT Q_OBJECT
public: public:
typedef QSharedPointer<CdbOptions> OptionsPtr;
enum CommandFlags { QuietCommand = 0x1 }; enum CommandFlags { QuietCommand = 0x1 };
// Flag bits for a sequence of commands // Flag bits for a sequence of commands
enum CommandSequenceFlags { enum CommandSequenceFlags {
@@ -74,7 +71,7 @@ public:
typedef void (CdbEngine::*BuiltinCommandHandler)(const CdbBuiltinCommandPtr &); typedef void (CdbEngine::*BuiltinCommandHandler)(const CdbBuiltinCommandPtr &);
typedef void (CdbEngine::*ExtensionCommandHandler)(const CdbExtensionCommandPtr &); typedef void (CdbEngine::*ExtensionCommandHandler)(const CdbExtensionCommandPtr &);
CdbEngine(const DebuggerStartParameters &sp, const OptionsPtr &options); CdbEngine(const DebuggerStartParameters &sp);
~CdbEngine(); ~CdbEngine();
// Factory function that returns 0 if the debug engine library cannot be found. // Factory function that returns 0 if the debug engine library cannot be found.
@@ -247,7 +244,6 @@ private:
const QByteArray m_creatorExtPrefix; const QByteArray m_creatorExtPrefix;
const QByteArray m_tokenPrefix; const QByteArray m_tokenPrefix;
const OptionsPtr m_options;
QProcess m_process; QProcess m_process;
QScopedPointer<Utils::ConsoleProcess> m_consoleStub; QScopedPointer<Utils::ConsoleProcess> m_consoleStub;

View File

@@ -1,117 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "cdboptions.h"
#include <QSettings>
static const char settingsGroupC[] = "CDB2";
static const char symbolPathsKeyC[] = "SymbolPaths";
static const char sourcePathsKeyC[] = "SourcePaths";
static const char breakEventKeyC[] = "BreakEvent";
static const char breakFunctionsKeyC[] = "BreakFunctions";
static const char additionalArgumentsKeyC[] = "AdditionalArguments";
static const char cdbConsoleKeyC[] = "CDB_Console";
static const char breakpointCorrectionKeyC[] = "BreakpointCorrection";
static const char ignoreFirstChanceAccessViolationKeyC[] = "IgnoreFirstChanceAccessViolation";
namespace Debugger {
namespace Internal {
const char *CdbOptions::crtDbgReport = "CrtDbgReport";
CdbOptions::CdbOptions()
: cdbConsole(false)
, breakpointCorrection(true)
, ignoreFirstChanceAccessViolation(false)
{
}
QString CdbOptions::settingsGroup()
{
return QLatin1String(settingsGroupC);
}
void CdbOptions::clear()
{
symbolPaths.clear();
sourcePaths.clear();
breakpointCorrection = true;
cdbConsole = ignoreFirstChanceAccessViolation = false;
breakEvents.clear();
breakFunctions.clear();
}
QStringList CdbOptions::oldEngineSymbolPaths(const QSettings *s)
{
return s->value(QLatin1String("CDB/SymbolPaths")).toStringList();
}
void CdbOptions::fromSettings(QSettings *s)
{
clear();
const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/');
additionalArguments = s->value(keyRoot + QLatin1String(additionalArgumentsKeyC), QString()).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();
breakFunctions = s->value(keyRoot + QLatin1String(breakFunctionsKeyC), QStringList()).toStringList();
cdbConsole = s->value(keyRoot + QLatin1String(cdbConsoleKeyC), QVariant(false)).toBool();
breakpointCorrection = s->value(keyRoot + QLatin1String(breakpointCorrectionKeyC), QVariant(true)).toBool();
ignoreFirstChanceAccessViolation = s->value(keyRoot + QLatin1String(ignoreFirstChanceAccessViolationKeyC), false).toBool();
}
void CdbOptions::toSettings(QSettings *s) const
{
s->beginGroup(QLatin1String(settingsGroupC));
s->setValue(QLatin1String(symbolPathsKeyC), symbolPaths);
s->setValue(QLatin1String(sourcePathsKeyC), sourcePaths);
s->setValue(QLatin1String(breakEventKeyC), breakEvents);
s->setValue(QLatin1String(breakFunctionsKeyC), breakFunctions);
s->setValue(QLatin1String(additionalArgumentsKeyC), additionalArguments);
s->setValue(QLatin1String(cdbConsoleKeyC), QVariant(cdbConsole));
s->setValue(QLatin1String(breakpointCorrectionKeyC), QVariant(breakpointCorrection));
s->setValue(QLatin1String(ignoreFirstChanceAccessViolationKeyC), QVariant(ignoreFirstChanceAccessViolation));
s->endGroup();
}
bool CdbOptions::equals(const CdbOptions &rhs) const
{
return cdbConsole == rhs.cdbConsole
&& breakpointCorrection == rhs.breakpointCorrection
&& ignoreFirstChanceAccessViolation == rhs.ignoreFirstChanceAccessViolation
&& additionalArguments == rhs.additionalArguments
&& symbolPaths == rhs.symbolPaths
&& sourcePaths == rhs.sourcePaths
&& breakEvents == rhs.breakEvents
&& breakFunctions == rhs.breakFunctions;
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,81 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CDBOPTIONS_H
#define CDBOPTIONS_H
#include <QStringList>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
struct CdbOptions
{
public:
CdbOptions();
void clear();
void fromSettings(QSettings *s); // Writes parameters on first-time autodetect
void toSettings(QSettings *s) const;
bool equals(const CdbOptions &rhs) const;
static QString settingsGroup();
static QStringList oldEngineSymbolPaths(const QSettings *s);
QString additionalArguments;
QStringList symbolPaths;
QStringList sourcePaths;
// Events to break on (Command 'sxe' with abbreviation and optional parameter)
QStringList breakEvents;
QStringList breakFunctions;
// Launch CDB's own console instead of Qt Creator's
bool cdbConsole;
// Perform code-model based correction of breakpoint location.
bool breakpointCorrection;
// Add -x to command line.
bool ignoreFirstChanceAccessViolation;
static const char *crtDbgReport;
};
inline bool operator==(const CdbOptions &s1, const CdbOptions &s2)
{ return s1.equals(s2); }
inline bool operator!=(const CdbOptions &s1, const CdbOptions &s2)
{ return !s1.equals(s2); }
} // namespace Internal
} // namespace Debugger
#endif // CDBOPTIONS_H

View File

@@ -29,6 +29,8 @@
#include "cdboptionspage.h" #include "cdboptionspage.h"
#include "commonoptionspage.h" #include "commonoptionspage.h"
#include "debuggeractions.h"
#include "debuggercore.h"
#include "debuggerinternalconstants.h" #include "debuggerinternalconstants.h"
#include "cdbengine.h" #include "cdbengine.h"
#include "cdbsymbolpathlisteditor.h" #include "cdbsymbolpathlisteditor.h"
@@ -41,6 +43,8 @@
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
const char *CdbOptionsPage::crtDbgReport = "CrtDbgReport";
struct EventsDescription { struct EventsDescription {
const char *abbreviation; const char *abbreviation;
bool hasParameter; bool hasParameter;
@@ -157,8 +161,6 @@ QStringList CdbBreakEventWidget::breakEvents() const
CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_breakEventWidget(new CdbBreakEventWidget) , m_breakEventWidget(new CdbBreakEventWidget)
, m_symbolPathListEditor(new CdbSymbolPathListEditor)
, m_sourcePathListEditor(new Utils::PathListEditor)
{ {
m_ui.setupUi(this); m_ui.setupUi(this);
// Squeeze the groupbox layouts vertically to // Squeeze the groupbox layouts vertically to
@@ -175,40 +177,25 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent)
eventLayout->addWidget(m_breakEventWidget); eventLayout->addWidget(m_breakEventWidget);
m_ui.eventGroupBox->setLayout(eventLayout); m_ui.eventGroupBox->setLayout(eventLayout);
m_ui.breakCrtDbgReportCheckBox m_ui.breakCrtDbgReportCheckBox
->setText(CommonOptionsPage::msgSetBreakpointAtFunction(CdbOptions::crtDbgReport)); ->setText(CommonOptionsPage::msgSetBreakpointAtFunction(CdbOptionsPage::crtDbgReport));
const QString hint = tr("This is useful to catch runtime error messages, for example caused by assert()."); const QString hint = tr("This is useful to catch runtime error messages, for example caused by assert().");
m_ui.breakCrtDbgReportCheckBox m_ui.breakCrtDbgReportCheckBox
->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(CdbOptions::crtDbgReport, hint)); ->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(CdbOptionsPage::crtDbgReport, hint));
m_ui.symbolPathsGroupBox->layout()->addWidget(m_symbolPathListEditor); DebuggerCore *dc = debuggerCore();
m_ui.sourcePathsGroupBox->layout()->addWidget(m_sourcePathListEditor); group.insert(dc->action(CdbAdditionalArguments), m_ui.additionalArgumentsLineEdit);
group.insert(dc->action(CdbBreakOnCrtDbgReport), m_ui.breakCrtDbgReportCheckBox);
group.insert(dc->action(UseCdbConsole), m_ui.consoleCheckBox);
group.insert(dc->action(CdbBreakPointCorrection), m_ui.breakpointCorrectionCheckBox);
group.insert(dc->action(IgnoreFirstChanceAccessViolation),
m_ui.ignoreFirstChanceAccessViolationCheckBox);
m_breakEventWidget->setBreakEvents(dc->stringListSetting(CdbBreakEvents));
} }
void CdbOptionsPageWidget::setOptions(CdbOptions &o) QStringList CdbOptionsPageWidget::breakEvents() const
{ {
m_ui.additionalArgumentsLineEdit->setText(o.additionalArguments); return m_breakEventWidget->breakEvents();
m_symbolPathListEditor->setPathList(o.symbolPaths);
m_sourcePathListEditor->setPathList(o.sourcePaths);
m_ui.ignoreFirstChanceAccessViolationCheckBox->setChecked(o.ignoreFirstChanceAccessViolation);
m_breakEventWidget->setBreakEvents(o.breakEvents);
m_ui.consoleCheckBox->setChecked(o.cdbConsole);
m_ui.breakpointCorrectionCheckBox->setChecked(o.breakpointCorrection);
m_ui.breakCrtDbgReportCheckBox->setChecked(o.breakFunctions.contains(QLatin1String(CdbOptions::crtDbgReport)));
}
CdbOptions CdbOptionsPageWidget::options() const
{
CdbOptions rc;
rc.additionalArguments = m_ui.additionalArgumentsLineEdit->text().trimmed();
rc.symbolPaths = m_symbolPathListEditor->pathList();
rc.sourcePaths = m_sourcePathListEditor->pathList();
rc.ignoreFirstChanceAccessViolation = m_ui.ignoreFirstChanceAccessViolationCheckBox->isChecked();
rc.breakEvents = m_breakEventWidget->breakEvents();
rc.cdbConsole = m_ui.consoleCheckBox->isChecked();
rc.breakpointCorrection = m_ui.breakpointCorrectionCheckBox->isChecked();
if (m_ui.breakCrtDbgReportCheckBox->isChecked())
rc.breakFunctions.push_back(QLatin1String(CdbOptions::crtDbgReport));
return rc;
} }
static QString stripColon(QString s) static QString stripColon(QString s)
@@ -222,24 +209,15 @@ static QString stripColon(QString s)
QString CdbOptionsPageWidget::searchKeywords() const QString CdbOptionsPageWidget::searchKeywords() const
{ {
QString rc; QString rc;
QTextStream(&rc) QTextStream(&rc) << stripColon(m_ui.additionalArgumentsLabel->text());
<< stripColon(m_ui.additionalArgumentsLabel->text()) << ' '
<< m_ui.symbolPathsGroupBox->title() << ' '
<< m_ui.sourcePathsGroupBox->title();
rc.remove(QLatin1Char('&')); rc.remove(QLatin1Char('&'));
return rc; return rc;
} }
// ---------- CdbOptionsPage // ---------- CdbOptionsPage
CdbOptionsPage *CdbOptionsPage::m_instance = 0; CdbOptionsPage::CdbOptionsPage()
CdbOptionsPage::CdbOptionsPage() :
m_options(new CdbOptions)
{ {
CdbOptionsPage::m_instance = this;
m_options->fromSettings(Core::ICore::settings());
setId("F.Cda"); setId("F.Cda");
setDisplayName(tr("CDB")); setDisplayName(tr("CDB"));
setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY); setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
@@ -250,13 +228,11 @@ CdbOptionsPage::CdbOptionsPage() :
CdbOptionsPage::~CdbOptionsPage() CdbOptionsPage::~CdbOptionsPage()
{ {
CdbOptionsPage::m_instance = 0;
} }
QWidget *CdbOptionsPage::createPage(QWidget *parent) QWidget *CdbOptionsPage::createPage(QWidget *parent)
{ {
m_widget = new CdbOptionsPageWidget(parent); m_widget = new CdbOptionsPageWidget(parent);
m_widget->setOptions(*m_options);
if (m_searchKeywords.isEmpty()) if (m_searchKeywords.isEmpty())
m_searchKeywords = m_widget->searchKeywords(); m_searchKeywords = m_widget->searchKeywords();
return m_widget; return m_widget;
@@ -266,15 +242,13 @@ void CdbOptionsPage::apply()
{ {
if (!m_widget) if (!m_widget)
return; return;
const CdbOptions newOptions = m_widget->options(); m_widget->group.apply(Core::ICore::settings());
if (*m_options != newOptions) { debuggerCore()->action(CdbBreakEvents)->setValue(m_widget->breakEvents());
*m_options = newOptions;
m_options->toSettings(Core::ICore::settings());
}
} }
void CdbOptionsPage::finish() void CdbOptionsPage::finish()
{ {
m_widget->group.finish();
} }
bool CdbOptionsPage::matches(const QString &s) const bool CdbOptionsPage::matches(const QString &s) const
@@ -282,9 +256,91 @@ bool CdbOptionsPage::matches(const QString &s) const
return m_searchKeywords.contains(s, Qt::CaseInsensitive); return m_searchKeywords.contains(s, Qt::CaseInsensitive);
} }
CdbOptionsPage *CdbOptionsPage::instance() // ---------- CdbPathsPage
class CdbPathsPageWidget : public QWidget
{ {
return m_instance; public:
Utils::SavedActionSet group;
// CdbPaths m_paths;
QString m_searchKeywords;
CdbSymbolPathListEditor *m_symbolPathListEditor;
Utils::PathListEditor *m_sourcePathListEditor;
CdbPathsPageWidget(QWidget *parent = 0);
};
CdbPathsPageWidget::CdbPathsPageWidget(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);
QString title = tr("Symbol Paths");
m_searchKeywords.append(title);
QGroupBox* gbSymbolPath = new QGroupBox(this);
gbSymbolPath->setTitle(title);
QVBoxLayout *gbSymbolPathLayout = new QVBoxLayout(gbSymbolPath);
m_symbolPathListEditor = new CdbSymbolPathListEditor(gbSymbolPath);
gbSymbolPathLayout->addWidget(m_symbolPathListEditor);
title = tr("Source Paths");
m_searchKeywords.append(title);
QGroupBox* gbSourcePath = new QGroupBox(this);
gbSourcePath->setTitle(title);
QVBoxLayout *gbSourcePathLayout = new QVBoxLayout(gbSourcePath);
m_sourcePathListEditor = new Utils::PathListEditor(gbSourcePath);
gbSourcePathLayout->addWidget(m_sourcePathListEditor);
layout->addWidget(gbSymbolPath);
layout->addWidget(gbSourcePath);
DebuggerCore *dc = debuggerCore();
group.insert(dc->action(CdbSymbolPaths), m_symbolPathListEditor);
group.insert(dc->action(CdbSourcePaths), m_sourcePathListEditor);
}
CdbPathsPage::CdbPathsPage()
: m_widget(0)
{
setId("F.Cdb");
setDisplayName(tr("CDB Paths"));
setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
setDisplayCategory(QCoreApplication::translate("Debugger",
Constants::DEBUGGER_SETTINGS_TR_CATEGORY));
setCategoryIcon(QLatin1String(Constants::DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON));
}
CdbPathsPage::~CdbPathsPage()
{
}
QWidget *CdbPathsPage::createPage(QWidget *parent)
{
if (!m_widget)
m_widget = new CdbPathsPageWidget(parent);
else
m_widget->setParent(parent);
return m_widget;
}
void CdbPathsPage::apply()
{
if (m_widget)
m_widget->group.apply(Core::ICore::settings());
}
void CdbPathsPage::finish()
{
if (m_widget)
m_widget->group.finish();
}
bool CdbPathsPage::matches(const QString &searchKeyWord) const
{
return m_widget &&
m_widget->m_searchKeywords.contains(searchKeyWord, Qt::CaseInsensitive);
} }
} // namespace Internal } // namespace Internal

View File

@@ -30,13 +30,13 @@
#ifndef CDBOPTIONSPAGE_H #ifndef CDBOPTIONSPAGE_H
#define CDBOPTIONSPAGE_H #define CDBOPTIONSPAGE_H
#include "cdboptions.h"
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <utils/savedaction.h>
#include "ui_cdboptionspagewidget.h" #include "ui_cdboptionspagewidget.h"
#include <QPointer> #include <QPointer>
#include <QSharedPointer> #include <QSharedPointer>
#include <QStringList>
#include <QDialog> #include <QDialog>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -50,6 +50,7 @@ namespace Debugger {
namespace Internal { namespace Internal {
class CdbSymbolPathListEditor; class CdbSymbolPathListEditor;
class CdbPathsPageWidget;
// Widget displaying a list of break events for the 'sxe' command // Widget displaying a list of break events for the 'sxe' command
// with a checkbox to enable 'break' and optionally a QLineEdit for // with a checkbox to enable 'break' and optionally a QLineEdit for
@@ -78,15 +79,15 @@ class CdbOptionsPageWidget : public QWidget
public: public:
explicit CdbOptionsPageWidget(QWidget *parent); explicit CdbOptionsPageWidget(QWidget *parent);
QStringList breakEvents() const;
void setOptions(CdbOptions &o);
CdbOptions options() const;
QString searchKeywords() const; QString searchKeywords() const;
Utils::SavedActionSet group;
private: private:
inline QString path() const; inline QString path() const;
Ui::CdbOptionsPageWidget m_ui; Ui::CdbOptionsPageWidget m_ui;
CdbBreakEventWidget *m_breakEventWidget; CdbBreakEventWidget *m_breakEventWidget;
CdbSymbolPathListEditor *m_symbolPathListEditor; CdbSymbolPathListEditor *m_symbolPathListEditor;
@@ -101,23 +102,40 @@ public:
explicit CdbOptionsPage(); explicit CdbOptionsPage();
virtual ~CdbOptionsPage(); virtual ~CdbOptionsPage();
static CdbOptionsPage *instance();
// IOptionsPage // IOptionsPage
QWidget *createPage(QWidget *parent); QWidget *createPage(QWidget *parent);
void apply(); void apply();
void finish(); void finish();
bool matches(const QString &) const; bool matches(const QString &) const;
QSharedPointer<CdbOptions> options() const { return m_options; } static const char *crtDbgReport;
private: private:
static CdbOptionsPage *m_instance; Utils::SavedActionSet group;
const QSharedPointer<CdbOptions> m_options;
QPointer<CdbOptionsPageWidget> m_widget; QPointer<CdbOptionsPageWidget> m_widget;
QString m_searchKeywords; QString m_searchKeywords;
}; };
class CdbPathsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
explicit CdbPathsPage();
virtual ~CdbPathsPage();
static CdbPathsPage *instance();
// IOptionsPage
QWidget *createPage(QWidget *parent);
void apply();
void finish();
bool matches(const QString &searchKeyWord) const;
private:
QPointer<CdbPathsPageWidget> m_widget;
};
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger

View File

@@ -96,22 +96,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QGroupBox" name="symbolPathsGroupBox">
<property name="title">
<string>Symbol Paths</string>
</property>
<layout class="QGridLayout" name="gridLayout_3"/>
</widget>
</item>
<item>
<widget class="QGroupBox" name="sourcePathsGroupBox">
<property name="title">
<string>Source Paths</string>
</property>
<layout class="QGridLayout" name="gridLayout_4"/>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View File

@@ -149,8 +149,6 @@ QtcPlugin {
"cdb/bytearrayinputstream.h", "cdb/bytearrayinputstream.h",
"cdb/cdbengine.cpp", "cdb/cdbengine.cpp",
"cdb/cdbengine.h", "cdb/cdbengine.h",
"cdb/cdboptions.cpp",
"cdb/cdboptions.h",
"cdb/cdboptionspage.cpp", "cdb/cdboptionspage.cpp",
"cdb/cdboptionspage.h", "cdb/cdboptionspage.h",
"cdb/cdboptionspagewidget.ui", "cdb/cdboptionspagewidget.ui",

View File

@@ -42,6 +42,7 @@
using namespace Utils; using namespace Utils;
static const char debugModeSettingsGroupC[] = "DebugMode"; static const char debugModeSettingsGroupC[] = "DebugMode";
static const char cdbSettingsGroupC[] = "CDB2";
static const char sourcePathMappingArrayNameC[] = "SourcePathMappings"; static const char sourcePathMappingArrayNameC[] = "SourcePathMappings";
static const char sourcePathMappingSourceKeyC[] = "Source"; static const char sourcePathMappingSourceKeyC[] = "Source";
static const char sourcePathMappingTargetKeyC[] = "Target"; static const char sourcePathMappingTargetKeyC[] = "Target";
@@ -91,6 +92,7 @@ DebuggerSettings::DebuggerSettings(QSettings *settings)
{ {
m_settings = settings; m_settings = settings;
const QString debugModeGroup = QLatin1String(debugModeSettingsGroupC); const QString debugModeGroup = QLatin1String(debugModeSettingsGroupC);
const QString cdbSettingsGroup = QLatin1String(cdbSettingsGroupC);
SavedAction *item = 0; SavedAction *item = 0;
@@ -224,6 +226,54 @@ DebuggerSettings::DebuggerSettings(QSettings *settings)
"level.")); "level."));
insertItem(AutoDerefPointers, item); insertItem(AutoDerefPointers, item);
//
// Cdb Options
//
item = new SavedAction(this);
item->setDefaultValue(QString());
item->setSettingsKey(cdbSettingsGroup, QLatin1String("AdditionalArguments"));
insertItem(CdbAdditionalArguments, item);
item = new SavedAction(this);
item->setDefaultValue(QStringList());
item->setSettingsKey(cdbSettingsGroup, QLatin1String("SymbolPaths"));
insertItem(CdbSymbolPaths, item);
item = new SavedAction(this);
item->setDefaultValue(QStringList());
item->setSettingsKey(cdbSettingsGroup, QLatin1String("SourcePaths"));
insertItem(CdbSourcePaths, item);
item = new SavedAction(this);
item->setDefaultValue(QStringList());
item->setSettingsKey(cdbSettingsGroup, QLatin1String("BreakEvent"));
insertItem(CdbBreakEvents, item);
item = new SavedAction(this);
item->setCheckable(true);
item->setDefaultValue(false);
item->setSettingsKey(cdbSettingsGroup, QLatin1String("BreakOnCrtDbgReport"));
insertItem(CdbBreakOnCrtDbgReport, item);
item = new SavedAction(this);
item->setCheckable(true);
item->setDefaultValue(false);
item->setSettingsKey(cdbSettingsGroup, QLatin1String("CDB_Console"));
insertItem(UseCdbConsole, item);
item = new SavedAction(this);
item->setCheckable(true);
item->setDefaultValue(true);
item->setSettingsKey(cdbSettingsGroup, QLatin1String("BreakpointCorrection"));
insertItem(CdbBreakPointCorrection, item);
item = new SavedAction(this);
item->setCheckable(true);
item->setDefaultValue(false);
item->setSettingsKey(cdbSettingsGroup, QLatin1String("IgnoreFirstChanceAccessViolation"));
insertItem(IgnoreFirstChanceAccessViolation, item);
// //
// Locals & Watchers // Locals & Watchers
// //

View File

@@ -115,6 +115,16 @@ enum DebuggerActionCode
RegisterForPostMortem, RegisterForPostMortem,
// Cdb
CdbAdditionalArguments,
CdbSymbolPaths,
CdbSourcePaths,
CdbBreakEvents,
CdbBreakOnCrtDbgReport,
UseCdbConsole,
CdbBreakPointCorrection,
IgnoreFirstChanceAccessViolation,
// Gdb // Gdb
LoadGdbInit, LoadGdbInit,
LoadGdbDumpers, LoadGdbDumpers,

View File

@@ -208,8 +208,7 @@ int CdbSymbolPathListEditor::indexOfSymbolPath(const QStringList &paths,
return -1; return -1;
} }
bool CdbSymbolPathListEditor::promptToAddSymbolPaths(const QString &settingsGroup, bool CdbSymbolPathListEditor::promptToAddSymbolPaths(QStringList *symbolPaths)
QStringList *symbolPaths)
{ {
const int indexOfSymbolServer = const int indexOfSymbolServer =
CdbSymbolPathListEditor::indexOfSymbolPath(*symbolPaths, SymbolServerPath); CdbSymbolPathListEditor::indexOfSymbolPath(*symbolPaths, SymbolServerPath);
@@ -220,7 +219,7 @@ bool CdbSymbolPathListEditor::promptToAddSymbolPaths(const QString &settingsGrou
|| (indexOfSymbolServer != -1 && indexOfSymbolCache != -1)) || (indexOfSymbolServer != -1 && indexOfSymbolCache != -1))
return false; return false;
const QString nagSymbolServerKey = settingsGroup + QLatin1String("/NoPromptSymbolCache"); const QString nagSymbolServerKey = QLatin1String("CDB2/NoPromptSymbolCache");
bool noFurtherNagging = Core::ICore::settings()->value(nagSymbolServerKey, false).toBool(); bool noFurtherNagging = Core::ICore::settings()->value(nagSymbolServerKey, false).toBool();
if (noFurtherNagging) if (noFurtherNagging)
return false; return false;

View File

@@ -95,7 +95,7 @@ public:
static int indexOfSymbolPath(const QStringList &paths, SymbolPathMode mode, QString *cacheDir = 0); static int indexOfSymbolPath(const QStringList &paths, SymbolPathMode mode, QString *cacheDir = 0);
// Nag user to add a symbol cache and server to the path list on debugger startup. // Nag user to add a symbol cache and server to the path list on debugger startup.
static bool promptToAddSymbolPaths(const QString &settingsGroup, QStringList *symbolPaths); static bool promptToAddSymbolPaths(QStringList *symbolPaths);
private: private:
void addSymbolPath(SymbolPathMode mode); void addSymbolPath(SymbolPathMode mode);