diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2012-08-28 14:37:18 +0200 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2012-08-29 08:18:16 +0200 |
commit | 5409d2d1d3491b83c6e4cf9a22c6d15fca2d3361 (patch) | |
tree | 32558250f2f6757486e7f548d50f4785d2d83d3d | |
parent | d07e7d2aab42105ead451c5381ddc0b52994b6b1 (diff) | |
download | qt-creator-5409d2d1d3491b83c6e4cf9a22c6d15fca2d3361.tar.gz |
CDB: Add setting to add breakpoint at CrtDbgReport().
- Factor out message/tooltips for breakpoints on functions.
- Add stringlist of break functions to CdbOptions.
- Set breakpoints with module, ignore response.
Change-Id: If5cf7647b190057c18d8499b9f4862696610e4f6
Reviewed-by: hjk <qthjk@ovi.com>
-rw-r--r-- | src/plugins/debugger/cdb/cdbengine.cpp | 49 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptions.cpp | 10 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptions.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptionspage.cpp | 9 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptionspagewidget.ui | 12 | ||||
-rw-r--r-- | src/plugins/debugger/commonoptionspage.cpp | 18 | ||||
-rw-r--r-- | src/plugins/debugger/commonoptionspage.h | 4 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdboptionspage.cpp | 19 |
8 files changed, 111 insertions, 13 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index a88b7e9e4e..12de1c163e 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -775,12 +775,59 @@ void CdbEngine::setupInferior() postExtensionCommand("pid", QByteArray(), 0, &CdbEngine::handlePid); } +static QByteArray msvcRunTime(const Abi::OSFlavor flavour) +{ + switch (flavour) { + case Abi::WindowsMsvc2005Flavor: + return "MSVCR80"; + case Abi::WindowsMsvc2008Flavor: + return "MSVCR90"; + case Abi::WindowsMsvc2010Flavor: + return "MSVCR100"; + case Abi::WindowsMsvc2012Flavor: + return "MSVCR110"; // #FIXME: VS2012 beta, will probably be 12 in final? + default: + break; + } + return "MSVCRT"; // MinGW, others. +} + +static QByteArray breakAtFunctionCommand(const QByteArray &function, + const QByteArray &module = QByteArray()) +{ + QByteArray result = "bu "; + if (!module.isEmpty()) { + result += module; + result += '!'; + } + result += function; + return result; +} + void CdbEngine::runEngine() { if (debug) qDebug("runEngine"); foreach (const QString &breakEvent, m_options->breakEvents) postCommand(QByteArray("sxe ") + breakEvent.toAscii(), 0); + // Break functions: each function must be fully qualified, + // else the debugger will slow down considerably. + foreach (const QString &breakFunctionS, m_options->breakFunctions) { + 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 debugModule = module + 'D'; + const QByteArray wideFunc = breakFunction + 'W'; + postCommand(breakAtFunctionCommand(breakFunction, module), 0); + postCommand(breakAtFunctionCommand(wideFunc, module), 0); + postCommand(breakAtFunctionCommand(breakFunction, debugModule), 0); + postCommand(breakAtFunctionCommand(wideFunc, debugModule), 0); + } else { + postCommand(breakAtFunctionCommand(breakFunction), 0); + } + } if (startParameters().startMode == AttachCore) { QTC_ASSERT(!m_coreStopReason.isNull(), return; ); notifyInferiorUnrunnable(); @@ -2990,6 +3037,8 @@ void CdbEngine::handleBreakPoints(const GdbMi &value) qPrintable(reportedResponse.toString())); if (reportedResponse.id.isValid() && !reportedResponse.pending) { const BreakpointModelId mid = handler->findBreakpointByResponseId(reportedResponse.id); + if (!mid.isValid() && reportedResponse.type == BreakpointByFunction) + continue; // Breakpoints from options, CrtDbgReport() and others. QTC_ASSERT(mid.isValid(), continue); const PendingBreakPointMap::iterator it = m_pendingBreakpointMap.find(mid); if (it != m_pendingBreakpointMap.end()) { diff --git a/src/plugins/debugger/cdb/cdboptions.cpp b/src/plugins/debugger/cdb/cdboptions.cpp index 413b2763c8..1c629da941 100644 --- a/src/plugins/debugger/cdb/cdboptions.cpp +++ b/src/plugins/debugger/cdb/cdboptions.cpp @@ -36,6 +36,7 @@ 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"; @@ -43,6 +44,8 @@ static const char breakpointCorrectionKeyC[] = "BreakpointCorrection"; namespace Debugger { namespace Internal { +const char *CdbOptions::crtDbgReport = "CrtDbgReport"; + CdbOptions::CdbOptions() : cdbConsole(false), breakpointCorrection(true) { } @@ -57,6 +60,8 @@ void CdbOptions::clear() symbolPaths.clear(); sourcePaths.clear(); cdbConsole = false; + breakEvents.clear(); + breakFunctions.clear(); } QStringList CdbOptions::oldEngineSymbolPaths(const QSettings *s) @@ -72,6 +77,7 @@ void CdbOptions::fromSettings(QSettings *s) 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(); } @@ -82,6 +88,7 @@ void CdbOptions::toSettings(QSettings *s) const 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)); @@ -95,7 +102,8 @@ bool CdbOptions::equals(const CdbOptions &rhs) const && additionalArguments == rhs.additionalArguments && symbolPaths == rhs.symbolPaths && sourcePaths == rhs.sourcePaths - && breakEvents == rhs.breakEvents; + && breakEvents == rhs.breakEvents + && breakFunctions == rhs.breakFunctions; } } // namespace Internal diff --git a/src/plugins/debugger/cdb/cdboptions.h b/src/plugins/debugger/cdb/cdboptions.h index 7e29a3eb05..f681c5e9f0 100644 --- a/src/plugins/debugger/cdb/cdboptions.h +++ b/src/plugins/debugger/cdb/cdboptions.h @@ -62,10 +62,13 @@ public: 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; + + static const char *crtDbgReport; }; inline bool operator==(const CdbOptions &s1, const CdbOptions &s2) diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp index a8b09f35fc..2ee23b4c11 100644 --- a/src/plugins/debugger/cdb/cdboptionspage.cpp +++ b/src/plugins/debugger/cdb/cdboptionspage.cpp @@ -30,6 +30,7 @@ #include "cdboptionspage.h" #include "cdboptions.h" +#include "commonoptionspage.h" #include "debuggerinternalconstants.h" #include "cdbengine.h" @@ -176,6 +177,11 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) : eventLayout->setContentsMargins(margins); eventLayout->addWidget(m_breakEventWidget); m_ui.eventGroupBox->setLayout(eventLayout); + m_ui.breakCrtDbgReportCheckBox + ->setText(CommonOptionsPage::msgSetBreakpointAtFunction(CdbOptions::crtDbgReport)); + const QString hint = tr("This is useful to catch runtime error messages, for example caused by assert()."); + m_ui.breakCrtDbgReportCheckBox + ->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(CdbOptions::crtDbgReport, hint)); } void CdbOptionsPageWidget::setOptions(CdbOptions &o) @@ -186,6 +192,7 @@ void CdbOptionsPageWidget::setOptions(CdbOptions &o) 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 @@ -197,6 +204,8 @@ CdbOptions CdbOptionsPageWidget::options() const 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; } diff --git a/src/plugins/debugger/cdb/cdboptionspagewidget.ui b/src/plugins/debugger/cdb/cdboptionspagewidget.ui index 8160cd74db..41b3d6a1ff 100644 --- a/src/plugins/debugger/cdb/cdboptionspagewidget.ui +++ b/src/plugins/debugger/cdb/cdboptionspagewidget.ui @@ -121,6 +121,18 @@ </widget> </item> <item> + <widget class="QGroupBox" name="breakFunctionGroupBox"> + <property name="title"> + <string>Break on functions:</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="breakCrtDbgReportCheckBox"/> + </item> + </layout> + </widget> + </item> + <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp index 495f28af0f..06a74b5235 100644 --- a/src/plugins/debugger/commonoptionspage.cpp +++ b/src/plugins/debugger/commonoptionspage.cpp @@ -200,6 +200,24 @@ bool CommonOptionsPage::matches(const QString &s) const return m_searchKeywords.contains(s, Qt::CaseInsensitive); } +QString CommonOptionsPage::msgSetBreakpointAtFunction(const char *function) +{ + return tr("Stop when %1() is called").arg(QLatin1String(function)); +} + +QString CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(const char *function, + const QString &hint) +{ + QString result = QLatin1String("<html><head/><body>"); + result += tr("Always add a breakpoint on the <i>%1()</i> function.").arg(QLatin1String(function)); + if (!hint.isEmpty()) { + result += QLatin1String("<br>"); + result += hint; + } + result += QLatin1String("</body></html>"); + return result; +} + /////////////////////////////////////////////////////////////////////// // // LocalsAndExpressionsOptionsPage diff --git a/src/plugins/debugger/commonoptionspage.h b/src/plugins/debugger/commonoptionspage.h index b5eaf9392a..4f5b76ab2c 100644 --- a/src/plugins/debugger/commonoptionspage.h +++ b/src/plugins/debugger/commonoptionspage.h @@ -79,6 +79,10 @@ public: void finish(); bool matches(const QString &s) const; + static QString msgSetBreakpointAtFunction(const char *function); + static QString msgSetBreakpointAtFunctionToolTip(const char *function, + const QString &hint = QString()); + private: const QSharedPointer<GlobalDebuggerOptions> m_options; QSharedPointer<Utils::SavedActionSet> m_group; diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp index 5f3bc80efa..4d11152141 100644 --- a/src/plugins/debugger/gdb/gdboptionspage.cpp +++ b/src/plugins/debugger/gdb/gdboptionspage.cpp @@ -29,6 +29,7 @@ **************************************************************************/ #include "gdboptionspage.h" +#include "commonoptionspage.h" #include "debuggeractions.h" #include "debuggercore.h" #include "debuggerinternalconstants.h" @@ -181,22 +182,16 @@ GdbOptionsPageWidget::GdbOptionsPageWidget(QWidget *parent) "when starting GDB.</body></html>")); checkBoxBreakOnWarning = new QCheckBox(groupBoxGeneral); - checkBoxBreakOnWarning->setText(GdbOptionsPage::tr("Stop when qWarning() is called")); - checkBoxBreakOnWarning->setToolTip(GdbOptionsPage::tr( - "<html><head/><body>Always add a breakpoint on the <i>qWarning()</i> function." - "</body></html>")); + checkBoxBreakOnWarning->setText(CommonOptionsPage::msgSetBreakpointAtFunction("qWarning")); + checkBoxBreakOnWarning->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip("qWarning")); checkBoxBreakOnFatal = new QCheckBox(groupBoxGeneral); - checkBoxBreakOnFatal->setText(GdbOptionsPage::tr("Stop when qFatal() is called")); - checkBoxBreakOnFatal->setToolTip(GdbOptionsPage::tr( - "<html><head/><body>Always add a breakpoint on the <i>qFatal()</i> function." - "</body></html>")); + checkBoxBreakOnFatal->setText(CommonOptionsPage::msgSetBreakpointAtFunction("qFatal")); + checkBoxBreakOnFatal->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip("qFatal")); checkBoxBreakOnAbort = new QCheckBox(groupBoxGeneral); - checkBoxBreakOnAbort->setText(GdbOptionsPage::tr("Stop when abort() is called")); - checkBoxBreakOnAbort->setToolTip(GdbOptionsPage::tr( - "<html><head/><body><p>Always add a breakpoint on the <i>abort()</i> function." - "</p></body></html>")); + checkBoxBreakOnAbort->setText(CommonOptionsPage::msgSetBreakpointAtFunction("abort")); + checkBoxBreakOnAbort->setText(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip("abort")); checkBoxEnableReverseDebugging = new QCheckBox(groupBoxGeneral); checkBoxEnableReverseDebugging->setText(GdbOptionsPage::tr("Enable reverse debugging")); |