diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index edc666d7342..86acab94c44 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -321,6 +321,8 @@ void BreakHandler::saveBreakpoints() map.insert(_("threadspec"), data.threadSpec); if (!data.enabled) map.insert(_("disabled"), one); + if (data.oneShot) + map.insert(_("oneshot"), one); if (data.pathUsage != BreakpointPathUsageEngineDefault) map.insert(_("usefullpath"), QString::number(data.pathUsage)); if (data.tracepoint) @@ -373,6 +375,9 @@ void BreakHandler::loadBreakpoints() v = map.value(_("disabled")); if (v.isValid()) data.enabled = !v.toInt(); + v = map.value(_("oneshot")); + if (v.isValid()) + data.oneShot = v.toInt(); v = map.value(_("usefullpath")); if (v.isValid()) data.pathUsage = static_cast(v.toInt()); @@ -768,6 +773,13 @@ bool BreakHandler::isTracepoint(BreakpointModelId id) const return it->data.tracepoint; } +bool BreakHandler::isOneShot(BreakpointModelId id) const +{ + ConstIterator it = m_storage.find(id); + BREAK_ASSERT(it != m_storage.end(), return false); + return it->data.oneShot; +} + bool BreakHandler::needsChildren(BreakpointModelId id) const { ConstIterator it = m_storage.find(id); diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index e1ca0db6a54..08c0fad0fdf 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -136,6 +136,7 @@ public: void updateLineNumberFromMarker(BreakpointModelId id, int lineNumber); void setMarkerFileAndLine(BreakpointModelId id, const QString &fileName, int lineNumber); + bool isOneShot(BreakpointModelId id) const; bool isWatchpoint(BreakpointModelId id) const; bool isTracepoint(BreakpointModelId id) const; void setTracepoint(BreakpointModelId, bool on); diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp index cc904fec759..cd0460fa661 100644 --- a/src/plugins/debugger/breakpoint.cpp +++ b/src/plugins/debugger/breakpoint.cpp @@ -180,7 +180,7 @@ BreakpointParameters::BreakpointParameters(BreakpointType t) : type(t), enabled(true), pathUsage(BreakpointPathUsageEngineDefault), ignoreCount(0), lineNumber(0), address(0), size(0), bitpos(0), bitsize(0), threadSpec(-1), - tracepoint(false) + tracepoint(false), oneShot(false) {} BreakpointParts BreakpointParameters::differencesTo @@ -215,31 +215,33 @@ BreakpointParts BreakpointParameters::differencesTo parts |= CommandPart; if (message != rhs.message) parts |= MessagePart; + if (oneShot != rhs.oneShot) + parts |= OneShotPart; return parts; } bool BreakpointParameters::isValid() const { switch (type) { - case Debugger::Internal::BreakpointByFileAndLine: + case BreakpointByFileAndLine: return !fileName.isEmpty() && lineNumber > 0; - case Debugger::Internal::BreakpointByFunction: + case BreakpointByFunction: return !functionName.isEmpty(); - case Debugger::Internal::WatchpointAtAddress: - case Debugger::Internal::BreakpointByAddress: + case WatchpointAtAddress: + case BreakpointByAddress: return address != 0; - case Debugger::Internal::BreakpointAtThrow: - case Debugger::Internal::BreakpointAtCatch: - case Debugger::Internal::BreakpointAtMain: - case Debugger::Internal::BreakpointAtFork: - case Debugger::Internal::BreakpointAtExec: - case Debugger::Internal::BreakpointAtSysCall: - case Debugger::Internal::BreakpointOnQmlSignalEmit: - case Debugger::Internal::BreakpointAtJavaScriptThrow: + case BreakpointAtThrow: + case BreakpointAtCatch: + case BreakpointAtMain: + case BreakpointAtFork: + case BreakpointAtExec: + case BreakpointAtSysCall: + case BreakpointOnQmlSignalEmit: + case BreakpointAtJavaScriptThrow: break; - case Debugger::Internal::WatchpointAtExpression: + case WatchpointAtExpression: return !expression.isEmpty(); - case Debugger::Internal::UnknownType: + case UnknownType: return false; } return true; diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h index 0e61e665f20..48d0060398a 100644 --- a/src/plugins/debugger/breakpoint.h +++ b/src/plugins/debugger/breakpoint.h @@ -174,7 +174,6 @@ enum BreakpointParts ConditionPart = 0x10, IgnoreCountPart = 0x20, ThreadSpecPart = 0x40, - AllConditionParts = ConditionPart|IgnoreCountPart|ThreadSpecPart, ModulePart = 0x80, TracePointPart = 0x100, @@ -183,11 +182,16 @@ enum BreakpointParts PathUsagePart = 0x800, CommandPart = 0x1000, MessagePart = 0x2000, + OneShotPart = 0x4000, + + AllConditionParts = ConditionPart|IgnoreCountPart|ThreadSpecPart + |OneShotPart, AllParts = FileAndLinePart|FunctionPart |ExpressionPart|AddressPart|ConditionPart |IgnoreCountPart|ThreadSpecPart|ModulePart|TracePointPart |EnabledPart|TypePart|PathUsagePart|CommandPart|MessagePart + |OneShotPart }; inline void operator|=(BreakpointParts &p, BreakpointParts r) @@ -234,6 +238,7 @@ public: QString command; //!< command to execute QString message; //!< message bool tracepoint; + bool oneShot; //!< Should this breakpoint trigger only once? }; class BreakpointResponse : public BreakpointParameters diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp index 2c555421a28..83ca9bf359b 100644 --- a/src/plugins/debugger/breakwindow.cpp +++ b/src/plugins/debugger/breakwindow.cpp @@ -128,6 +128,8 @@ private: QLineEdit *m_lineEditFunction; QLabel *m_labelTracepoint; QCheckBox *m_checkBoxTracepoint; + QLabel *m_labelOneShot; + QCheckBox *m_checkBoxOneShot; QLabel *m_labelUseFullPath; QLabel *m_labelModule; QLineEdit *m_lineEditModule; @@ -206,6 +208,10 @@ BreakpointDialog::BreakpointDialog(BreakpointModelId id, QWidget *parent) m_labelTracepoint = new QLabel(tr("T&racepoint only:"), groupBoxAdvanced); m_labelTracepoint->setBuddy(m_checkBoxTracepoint); + m_checkBoxOneShot = new QCheckBox(groupBoxAdvanced); + m_labelOneShot = new QLabel(tr("&One shot only:"), groupBoxAdvanced); + m_labelOneShot->setBuddy(m_checkBoxOneShot); + const QString pathToolTip = tr("

Determines how the path is specified " "when setting breakpoints: