From 29beabd5a4c712e3b2a7ee8be5a0e699627ed5d4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 16 Nov 2010 10:23:20 +0100 Subject: [PATCH] Debugger: Handle throw/catch/main as BreakpointType enum values. Remove BreakHandler::hasPendingBreakpoints, handle new types in CDB and gdb. Start fixing Breakpoint-Dialog. Add assignment of Breakpointresponse from BreakpointParameters. Reviewed-by: hjk --- src/plugins/debugger/breakhandler.cpp | 20 ++--- src/plugins/debugger/breakhandler.h | 1 - src/plugins/debugger/breakpoint.cpp | 14 ++- src/plugins/debugger/breakpoint.h | 10 +-- src/plugins/debugger/breakwindow.cpp | 139 +++++++++++++++++------------ src/plugins/debugger/cdb/cdbbreakpoint.cpp | 69 +++++++------- src/plugins/debugger/cdb/cdbbreakpoint.h | 7 +- src/plugins/debugger/cdb/cdbengine.cpp | 12 +-- src/plugins/debugger/cdb/cdbmodules.cpp | 15 ++-- src/plugins/debugger/cdb/cdbmodules.h | 3 + src/plugins/debugger/gdb/gdbengine.cpp | 35 +++++--- 11 files changed, 184 insertions(+), 141 deletions(-) diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 4c13ab7c74..861995e3be 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -74,16 +74,6 @@ int BreakHandler::rowCount(const QModelIndex &parent) const return parent.isValid() ? 0 : m_storage.size(); } -// FIXME: Only used by cdb. Move there? -bool BreakHandler::hasPendingBreakpoints() const -{ - ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); - for ( ; it != et; ++it) - if (it->isPending()) - return true; - return false; -} - static inline bool fileNameMatch(const QString &f1, const QString &f2) { #ifdef Q_OS_WIN @@ -907,11 +897,21 @@ QString BreakHandler::BreakpointItem::toToolTip() const case BreakpointByAddress: t = tr("Breakpoint by Address"); break; + case BreakpointAtThrow: + t = tr("Breakpoint at \"throw\""); + break; + case BreakpointAtCatch: + t = tr("Breakpoint at \"catch\""); + break; + case BreakpointAtMain: + t = tr("Breakpoint at Function \"main()\""); + break; case Watchpoint: t = tr("Watchpoint"); break; case UnknownType: t = tr("Unknown Breakpoint Type"); + break; } QString rc; diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index 92093e444b..b8522aa388 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -68,7 +68,6 @@ public: BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const; BreakpointIds unclaimedBreakpointIds() const; int size() const { return m_storage.size(); } - bool hasPendingBreakpoints() const; // Find a breakpoint matching approximately the data in needle. BreakpointId findSimilarBreakpoint(const BreakpointResponse &needle) const; diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp index 4bad4221e7..de7133c8f4 100644 --- a/src/plugins/debugger/breakpoint.cpp +++ b/src/plugins/debugger/breakpoint.cpp @@ -41,9 +41,6 @@ namespace Internal { // ////////////////////////////////////////////////////////////////// -const char *BreakpointData::throwFunction = "throw"; -const char *BreakpointData::catchFunction = "catch"; - BreakpointParameters::BreakpointParameters(BreakpointType t) : type(t), enabled(true), useFullPath(false), ignoreCount(0), lineNumber(0), address(0) @@ -52,7 +49,7 @@ BreakpointParameters::BreakpointParameters(BreakpointType t) : bool BreakpointParameters::equals(const BreakpointParameters &rhs) const { - return type != rhs.type && enabled == rhs.enabled + return type == rhs.type && enabled == rhs.enabled && useFullPath == rhs.useFullPath && fileName == rhs.fileName && condition == rhs.condition && ignoreCount == rhs.ignoreCount && lineNumber == rhs.lineNumber @@ -168,5 +165,14 @@ QString BreakpointResponse::toString() const return result; } +void BreakpointResponse::fromParameters(const BreakpointParameters &p) +{ + BreakpointParameters::operator=(p); + number = 0; + fullName.clear(); + multiple = false; + state.clear(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h index 8b55716352..443eb92f99 100644 --- a/src/plugins/debugger/breakpoint.h +++ b/src/plugins/debugger/breakpoint.h @@ -62,8 +62,9 @@ enum BreakpointType BreakpointByFileAndLine, BreakpointByFunction, BreakpointByAddress, - //BreakpointAtThrow, // FIXME: actually use this - //BreakpointAtCatch, // FIXME: actually use this + BreakpointAtThrow, + BreakpointAtCatch, + BreakpointAtMain, Watchpoint, }; @@ -135,9 +136,6 @@ public: bool isWatchpoint() const { return type() == Watchpoint; } bool isBreakpoint() const { return type() != Watchpoint; } // Enough for now. - // Generic name for function to break on 'throw' - static const char *throwFunction; - static const char *catchFunction; private: // All setters return true on change. @@ -173,6 +171,8 @@ public: QString toString() const; public: + void fromParameters(const BreakpointParameters &p); + int number; // Breakpoint number assigned by the debugger engine. QString fullName; // Full file name acknowledged by the debugger engine. bool multiple; // Happens in constructors/gdb. diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp index f6f190a957..67944ee63d 100644 --- a/src/plugins/debugger/breakwindow.cpp +++ b/src/plugins/debugger/breakwindow.cpp @@ -69,72 +69,83 @@ public: explicit BreakpointDialog(QWidget *parent); bool showDialog(BreakpointData *data); + void setParameters(const BreakpointParameters &p); + BreakpointParameters parameters() const; + public slots: void typeChanged(int index); + +private: + void setType(BreakpointType type); + BreakpointType type() const; }; BreakpointDialog::BreakpointDialog(QWidget *parent) : QDialog(parent) { + // match BreakpointType (except unknown type) with additional item setupUi(this); - comboBoxType->insertItem(0, tr("File and Line Number")); - comboBoxType->insertItem(1, tr("Function Name")); - comboBoxType->insertItem(2, tr("Function \"main()\"")); - comboBoxType->insertItem(3, tr("Address")); + QStringList types; + types << tr("File and Line Number") << tr("Function Name") << tr("Address") + << tr("throw") << tr("catch") << tr("Function \"main()\"") + << tr("Address (Watchpoint)"); + QTC_ASSERT(types.size() == Watchpoint, return; ) + comboBoxType->addItems(types); pathChooserFileName->setExpectedKind(Utils::PathChooser::File); connect(comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int))); lineEditIgnoreCount->setValidator( new QIntValidator(0, 2147483647, lineEditIgnoreCount)); } -bool BreakpointDialog::showDialog(BreakpointData *data) +void BreakpointDialog::setType(BreakpointType type) +{ + const int comboIndex = type - 1; // Skip UnknownType + if (comboIndex != comboBoxType->currentIndex()) { + comboBoxType->setCurrentIndex(comboIndex); + typeChanged(comboIndex); + } +} + +BreakpointType BreakpointDialog::type() const { - pathChooserFileName->setPath(data->fileName()); - lineEditLineNumber->setText(QString::number(data->lineNumber())); - lineEditFunction->setText(data->functionName()); - lineEditCondition->setText(QString::fromUtf8(data->condition())); - lineEditIgnoreCount->setText(QString::number(data->ignoreCount())); - checkBoxUseFullPath->setChecked(data->useFullPath()); - lineEditThreadSpec->setText(QString::fromUtf8(data->threadSpec())); - const quint64 address = data->address(); + const int type = comboBoxType->currentIndex() + 1; // Skip unknown type + return static_cast(type); +} + +void BreakpointDialog::setParameters(const BreakpointParameters &p) +{ + pathChooserFileName->setPath(p.fileName); + lineEditLineNumber->setText(QString::number(p.lineNumber)); + lineEditFunction->setText(p.functionName); + lineEditCondition->setText(QString::fromUtf8(p.condition)); + lineEditIgnoreCount->setText(QString::number(p.ignoreCount)); + checkBoxUseFullPath->setChecked(p.useFullPath); + lineEditThreadSpec->setText(p.threadSpec); + const quint64 address = p.address; if (address) lineEditAddress->setText(QString::fromAscii("0x%1").arg(address, 0, 16)); - int initialType = 0; - if (!data->functionName().isEmpty()) - initialType = data->functionName() == QLatin1String("main") ? 2 : 1; - if (address) - initialType = 3; - typeChanged(initialType); - - if (exec() != QDialog::Accepted) - return false; + setType(p.type); +} - // Check if changed. - const int newLineNumber = lineEditLineNumber->text().toInt(); - const bool newUseFullPath = checkBoxUseFullPath->isChecked(); - const quint64 newAddress = lineEditAddress->text().toULongLong(0, 0); - const QString newFunction = lineEditFunction->text(); - const QString newFileName = pathChooserFileName->path(); - const QByteArray newCondition = lineEditCondition->text().toUtf8(); - const int newIgnoreCount = lineEditIgnoreCount->text().toInt(); - const QByteArray newThreadSpec = lineEditThreadSpec->text().toUtf8(); - - bool result = false; - result |= data->setAddress(newAddress); - result |= data->setFunctionName(newFunction); - result |= data->setUseFullPath(newUseFullPath); - result |= data->setFileName(newFileName); - result |= data->setLineNumber(newLineNumber); - result |= data->setCondition(newCondition); - result |= data->setIgnoreCount(newIgnoreCount); - result |= data->setThreadSpec(newThreadSpec); - return result; +BreakpointParameters BreakpointDialog::parameters() const +{ + BreakpointParameters rc(type()); + rc.lineNumber = lineEditLineNumber->text().toInt(); + rc.useFullPath = checkBoxUseFullPath->isChecked(); + rc.address = lineEditAddress->text().toULongLong(0, 0); + rc.functionName = lineEditFunction->text(); + rc.fileName = pathChooserFileName->path(); + rc.condition = lineEditCondition->text().toUtf8(); + rc.ignoreCount = lineEditIgnoreCount->text().toInt(); + rc.threadSpec = lineEditThreadSpec->text().toUtf8(); + return rc; } -void BreakpointDialog::typeChanged(int index) +void BreakpointDialog::typeChanged(int) { - const bool isLineVisible = index == 0; - const bool isFunctionVisible = index == 1; - const bool isAddressVisible = index == 3; + const BreakpointType t = type(); + const bool isLineVisible = t == BreakpointByFileAndLine; + const bool isFunctionVisible = t == BreakpointByFunction || t == BreakpointAtMain; + const bool isAddressVisible = t == BreakpointByAddress || t == Watchpoint; labelFileName->setEnabled(isLineVisible); pathChooserFileName->setEnabled(isLineVisible); labelLineNumber->setEnabled(isLineVisible); @@ -145,10 +156,34 @@ void BreakpointDialog::typeChanged(int index) lineEditFunction->setEnabled(isFunctionVisible); labelAddress->setEnabled(isAddressVisible); lineEditAddress->setEnabled(isAddressVisible); - if (index == 2) + if (t == BreakpointAtMain) lineEditFunction->setText(QLatin1String("main")); } +bool BreakpointDialog::showDialog(BreakpointData *data) +{ + setParameters(data->parameters()); + if (exec() != QDialog::Accepted) + return false; + + // Check if changed. + const BreakpointParameters newParameters = parameters(); + if (newParameters == data->parameters()) + return false; + + bool result = false; + result |= data->setType(newParameters.type); + result |= data->setAddress(newParameters.address); + result |= data->setFunctionName(newParameters.functionName); + result |= data->setUseFullPath(newParameters.useFullPath); + result |= data->setFileName(newParameters.fileName); + result |= data->setLineNumber(newParameters.lineNumber); + result |= data->setCondition(newParameters.condition); + result |= data->setIgnoreCount(newParameters.ignoreCount); + result |= data->setThreadSpec(newParameters.threadSpec); + return result; +} + /////////////////////////////////////////////////////////////////////// // // BreakWindow @@ -292,7 +327,6 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) synchronizeAction->setEnabled(debuggerCore()->hasSnapshots()); QModelIndex idx0 = (si.size() ? si.front() : QModelIndex()); - QModelIndex idx2 = idx0.sibling(idx0.row(), 2); const BreakpointId id = handler->findBreakpointByIndex(idx0); bool enabled = si.isEmpty() || handler->isEnabled(id); @@ -363,14 +397,9 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) else if (act == addBreakpointAction) addBreakpoint(); else if (act == breakAtThrowAction) { - BreakpointData data(BreakpointByFunction); - data.setFunctionName(BreakpointData::throwFunction); - handler->appendBreakpoint(data); + handler->appendBreakpoint(BreakpointData(BreakpointAtThrow)); } else if (act == breakAtCatchAction) { - // FIXME: Use the proper breakpoint type instead. - BreakpointData data(BreakpointByFunction); - data.setFunctionName(BreakpointData::catchFunction); - handler->appendBreakpoint(data); + handler->appendBreakpoint(BreakpointData(BreakpointAtCatch)); } } diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.cpp b/src/plugins/debugger/cdb/cdbbreakpoint.cpp index cbf5c2c68b..184c40c366 100644 --- a/src/plugins/debugger/cdb/cdbbreakpoint.cpp +++ b/src/plugins/debugger/cdb/cdbbreakpoint.cpp @@ -40,27 +40,27 @@ namespace Debugger { namespace Internal { // Convert breakpoint structs -static CdbCore::BreakPoint breakPointFromBreakPointData(const BreakpointData &bpd, const QString &functionName) +static CdbCore::BreakPoint breakPointFromBreakPointData(const BreakpointParameters &bpd, const QString &functionName) { CdbCore::BreakPoint rc; - rc.type = bpd.type() == Watchpoint ? + rc.type = bpd.type == Watchpoint ? CdbCore::BreakPoint::Data : CdbCore::BreakPoint::Code ; - rc.address = bpd.address(); - if (!bpd.threadSpec().isEmpty()) { + rc.address = bpd.address; + if (!bpd.threadSpec.isEmpty()) { bool ok; - rc.threadId = bpd.threadSpec().toInt(&ok); + rc.threadId = bpd.threadSpec.toInt(&ok); if (!ok) - qWarning("Cdb: Cannot convert breakpoint thread specification '%s'", bpd.threadSpec().constData()); + qWarning("Cdb: Cannot convert breakpoint thread specification '%s'", bpd.threadSpec.constData()); } - rc.fileName = QDir::toNativeSeparators(bpd.fileName()); - rc.condition = bpd.condition(); - rc.funcName = functionName.isEmpty() ? bpd.functionName() : functionName; - rc.ignoreCount = bpd.ignoreCount(); - rc.lineNumber = bpd.lineNumber(); + rc.fileName = QDir::toNativeSeparators(bpd.fileName); + rc.condition = bpd.condition; + rc.funcName = functionName.isEmpty() ? bpd.functionName : functionName; + rc.ignoreCount = bpd.ignoreCount; + rc.lineNumber = bpd.lineNumber; rc.oneShot = false; - rc.enabled = bpd.isEnabled(); + rc.enabled = bpd.enabled; return rc; } @@ -69,31 +69,38 @@ static inline QString msgCannotSetBreakAtFunction(const QString &func, const QSt return QString::fromLatin1("Cannot set a breakpoint at '%1': %2").arg(func, why); } -void setBreakpointResponse(const BreakpointData *nbd, int number, BreakpointResponse *response) +static inline BreakpointParameters transformBreakpoint(const BreakpointParameters &p) { - response->address = nbd->address(); - response->number = number; - response->functionName = nbd->functionName(); - response->type = nbd->type(); - response->condition = nbd->condition(); - response->ignoreCount = nbd->ignoreCount(); - response->fullName = response->fileName = nbd->fileName(); - response->lineNumber = nbd->lineNumber(); - response->threadSpec = nbd->threadSpec(); - response->enabled = nbd->isEnabled(); + if (p.type == BreakpointAtThrow) { + BreakpointParameters rc(BreakpointByFunction); + rc.functionName = QLatin1String(cdbThrowFunction); + return rc; + } + if (p.type == BreakpointAtCatch) { + BreakpointParameters rc(BreakpointByFunction); + rc.functionName = QLatin1String(cdbCatchFunction); + return rc; + } + if (p.type == BreakpointAtMain) { + BreakpointParameters rc(BreakpointByFunction); + rc.functionName = QLatin1String("main"); + return rc; + } + return p; } bool addCdbBreakpoint(CIDebugControl* debugControl, CIDebugSymbols *syms, - const BreakpointData *nbd, + const BreakpointParameters &bpIn, BreakpointResponse *response, QString *errorMessage) { + const BreakpointParameters bp = transformBreakpoint(bpIn); errorMessage->clear(); // Function breakpoints: Are the module names specified? QString resolvedFunction; - if (nbd->type() == BreakpointByFunction) { - resolvedFunction = nbd->functionName(); + if (bp.type == BreakpointByFunction) { + resolvedFunction = bp.functionName; switch (resolveSymbol(syms, &resolvedFunction, errorMessage)) { case ResolveSymbolOk: break; @@ -101,21 +108,23 @@ bool addCdbBreakpoint(CIDebugControl* debugControl, break; case ResolveSymbolNotFound: case ResolveSymbolError: - *errorMessage = msgCannotSetBreakAtFunction(nbd->functionName(), *errorMessage); + *errorMessage = msgCannotSetBreakAtFunction(bp.functionName, *errorMessage); return false; } if (debugBreakpoints) - qDebug() << nbd->functionName() << " resolved to " << resolvedFunction; + qDebug() << bp.functionName << " resolved to " << resolvedFunction; } // function breakpoint // Now add... quint64 address; unsigned long id; - const CdbCore::BreakPoint ncdbbp = breakPointFromBreakPointData(*nbd, resolvedFunction); + const CdbCore::BreakPoint ncdbbp = breakPointFromBreakPointData(bp, resolvedFunction); if (!ncdbbp.add(debugControl, errorMessage, &id, &address)) return false; if (debugBreakpoints) qDebug("Added %lu at 0x%lx %s", id, address, qPrintable(ncdbbp.toString())); - setBreakpointResponse(nbd, id, response); + + response->fromParameters(bp); + response->number = id; response->address = address; response->functionName = resolvedFunction; return true; diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.h b/src/plugins/debugger/cdb/cdbbreakpoint.h index 3a2d1ea626..f503186126 100644 --- a/src/plugins/debugger/cdb/cdbbreakpoint.h +++ b/src/plugins/debugger/cdb/cdbbreakpoint.h @@ -40,13 +40,13 @@ QT_END_NAMESPACE namespace Debugger { namespace Internal { -class BreakpointData; +class BreakpointParameters; class BreakpointResponse; // Convert breakpoint structs bool addCdbBreakpoint(CIDebugControl* debugControl, CIDebugSymbols *syms, - const BreakpointData *nbd, + const BreakpointParameters &bp, BreakpointResponse *response, QString *errorMessage); @@ -54,9 +54,6 @@ bool deleteCdbBreakpoints(CIDebugControl* debugControl, QString *errorMessage); void debugCdbBreakpoints(CIDebugControl* debugControl); -// Set response from data. -void setBreakpointResponse(const BreakpointData *nbd, int number, BreakpointResponse *response); - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index f99eed5381..6460bfdc9a 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -531,11 +531,7 @@ void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 ini } // Clear any saved breakpoints and set initial breakpoints m_engine->executeDebuggerCommand(QLatin1String("bc")); - if (m_engine->breakHandler()->hasPendingBreakpoints()) { - if (debugCDBExecution) - qDebug("processCreatedAttached: Syncing breakpoints"); - m_engine->attemptBreakpointSynchronization(); - } + m_engine->attemptBreakpointSynchronization(); // Attaching to crashed: This handshake (signalling an event) is required for // the exception to be delivered to the debugger // Also, see special handling in slotModulesLoaded(). @@ -1318,7 +1314,7 @@ bool CdbEngine::attemptBreakpointSynchronizationI(QString *errorMessage) switch (handler->state(id)) { case BreakpointInsertRequested: handler->setState(id, BreakpointInsertProceeding); - if (addCdbBreakpoint(control, symbols, data, &response, errorMessage)) { + if (addCdbBreakpoint(control, symbols, data->parameters(), &response, errorMessage)) { notifyBreakpointInsertOk(id); handler->setResponse(id, response); } else { @@ -1330,7 +1326,7 @@ bool CdbEngine::attemptBreakpointSynchronizationI(QString *errorMessage) // Skip disabled breakpoints, else add handler->setState(id, BreakpointChangeProceeding); if (data->isEnabled()) { - if (addCdbBreakpoint(control, symbols, data, &response, errorMessage)) { + if (addCdbBreakpoint(control, symbols, data->parameters(), &response, errorMessage)) { notifyBreakpointChangeOk(id); handler->setResponse(id, response); } else { @@ -1348,7 +1344,7 @@ bool CdbEngine::attemptBreakpointSynchronizationI(QString *errorMessage) case BreakpointPending: // Existing breakpoints were deleted due to change/removal, re-set if (syncType == BreakpointsRemovedChanged - && !addCdbBreakpoint(control, symbols, handler->breakpointById(id), &response, errorMessage)) + && !addCdbBreakpoint(control, symbols, handler->breakpointById(id)->parameters(), &response, errorMessage)) showMessage(*errorMessage, LogError); break; default: diff --git a/src/plugins/debugger/cdb/cdbmodules.cpp b/src/plugins/debugger/cdb/cdbmodules.cpp index c947468001..a90dcc884a 100644 --- a/src/plugins/debugger/cdb/cdbmodules.cpp +++ b/src/plugins/debugger/cdb/cdbmodules.cpp @@ -173,6 +173,9 @@ bool searchSymbols(CIDebugSymbols *syms, const QString &pattern, return true; } +const char *cdbThrowFunction = "CxxThrowException"; +const char *cdbCatchFunction = "__CxxCallCatchBlock"; + // Helper for the resolveSymbol overloads. static ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol, QStringList *matches, @@ -182,15 +185,9 @@ static ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol, // Is it an incomplete symbol? if (symbol->contains(QLatin1Char('!'))) return ResolveSymbolOk; - // Throw and catch - bool withinMSVCRunTime = false; - if (*symbol == QLatin1String(BreakpointData::throwFunction)) { - *symbol = QLatin1String("CxxThrowException"); - withinMSVCRunTime = true; - } else if (*symbol == QLatin1String(BreakpointData::catchFunction)) { - *symbol = QLatin1String("__CxxCallCatchBlock"); - withinMSVCRunTime = true; - } else if (*symbol == QLatin1String("qMain")) // 'main' is a #define for gdb, but not for VS + const bool withinMSVCRunTime = *symbol == QLatin1String(cdbThrowFunction) + || *symbol == QLatin1String(cdbCatchFunction); + if (*symbol == QLatin1String("qMain")) // 'main' is a #define for gdb, but not for VS *symbol = QLatin1String("main"); // resolve if (!searchSymbols(syms, *symbol, matches, errorMessage)) diff --git a/src/plugins/debugger/cdb/cdbmodules.h b/src/plugins/debugger/cdb/cdbmodules.h index 792ba526fa..c8fa65dad9 100644 --- a/src/plugins/debugger/cdb/cdbmodules.h +++ b/src/plugins/debugger/cdb/cdbmodules.h @@ -64,6 +64,9 @@ ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, const QString &pattern, bool getModuleSymbols(CIDebugSymbols *syms, const QString &moduleName, QList *symbols, QString *errorMessage); +extern const char *cdbThrowFunction; +extern const char *cdbCatchFunction; + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index f3659df0f5..e3e27a8690 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -2156,25 +2156,32 @@ static QByteArray addressSpec(quint64 address) QByteArray GdbEngine::breakpointLocation(BreakpointId id) { BreakHandler *handler = breakHandler(); - QByteArray functionName = handler->functionName(id).toUtf8(); - if (!functionName.isEmpty()) { - // FIXME: Use the types. - if (functionName == BreakpointData::throwFunction) - return "__cxa_throw"; - if (functionName == BreakpointData::catchFunction) - return "__cxa_begin_catch"; + const BreakpointData *data = handler->breakpointById(id); + QTC_ASSERT(data, return QByteArray()); + const BreakpointParameters parameters = data->parameters(); + // FIXME: Non-GCC-runtime + if (parameters.type == BreakpointAtThrow) + return "__cxa_throw"; + if (parameters.type == BreakpointAtCatch) + return "__cxa_begin_catch"; + if (parameters.type == BreakpointAtMain) +#ifdef Q_OS_WIN + return "qMain"; +#else + return "main"; +#endif + const QByteArray functionName = parameters.functionName.toUtf8(); + if (!functionName.isEmpty()) return functionName; - } - quint64 address = handler->address(id); - if (address) + if (const quint64 address = handler->address(id)) return addressSpec(address); // In this case, data->funcName is something like '*0xdeadbeef' - int lineNumber = handler->lineNumber(id); + const int lineNumber = handler->lineNumber(id); if (lineNumber == 0) return functionName; - QString fileName = handler->fileName(id); - if (handler->useFullPath(id)) - fileName = breakLocation(fileName); + const QString fileName = parameters.useFullPath ? + breakLocation(parameters.fileName) : + parameters.fileName; // The argument is simply a C-quoted version of the argument to the // non-MI "break" command, including the "original" quoting it wants. return "\"\\\"" + GdbMi::escapeCString(fileName).toLocal8Bit() + "\\\":" -- 2.11.0