Improve error logging of CDB breakpoint setting.

Output warnings to debugger log. Prevent breakpoints from
being set several times when loading session data by
clearing the complete break handler.
Reviewed-by: hjk <qtc-committer@nokia.com>
This commit is contained in:
Friedemann Kleint
2009-06-30 15:50:56 +02:00
parent 640278e1d0
commit e8dafc28a5
5 changed files with 70 additions and 34 deletions

View File

@@ -279,8 +279,12 @@ void BreakHandler::removeAt(int index)
void BreakHandler::clear() void BreakHandler::clear()
{ {
for (int index = size(); --index >= 0; ) qDeleteAll(m_bp);
removeAt(index); m_bp.clear();
m_enabled.clear();
m_disabled.clear();
m_removed.clear();
m_inserted.clear();
} }
int BreakHandler::findBreakpoint(const BreakpointData &needle) int BreakHandler::findBreakpoint(const BreakpointData &needle)
@@ -326,19 +330,19 @@ void BreakHandler::saveBreakpoints()
const BreakpointData *data = at(index); const BreakpointData *data = at(index);
QMap<QString, QVariant> map; QMap<QString, QVariant> map;
if (!data->fileName.isEmpty()) if (!data->fileName.isEmpty())
map["filename"] = data->fileName; map.insert(QLatin1String("filename"), data->fileName);
if (!data->lineNumber.isEmpty()) if (!data->lineNumber.isEmpty())
map["linenumber"] = data->lineNumber; map.insert(QLatin1String("linenumber"), data->lineNumber);
if (!data->funcName.isEmpty()) if (!data->funcName.isEmpty())
map["funcname"] = data->funcName; map.insert(QLatin1String("funcname"), data->funcName);
if (!data->condition.isEmpty()) if (!data->condition.isEmpty())
map["condition"] = data->condition; map.insert(QLatin1String("condition"), data->condition);
if (!data->ignoreCount.isEmpty()) if (!data->ignoreCount.isEmpty())
map["ignorecount"] = data->ignoreCount; map.insert(QLatin1String("ignorecount"), data->ignoreCount);
if (!data->enabled) if (!data->enabled)
map["disabled"] = "1"; map.insert(QLatin1String("disabled"), QLatin1String("1"));
if (data->useFullPath) if (data->useFullPath)
map["usefullpath"] = "1"; map.insert(QLatin1String("usefullpath"), QLatin1String("1"));
list.append(map); list.append(map);
} }
setSessionValueRequested("Breakpoints", list); setSessionValueRequested("Breakpoints", list);
@@ -349,18 +353,31 @@ void BreakHandler::loadBreakpoints()
QVariant value; QVariant value;
sessionValueRequested("Breakpoints", &value); sessionValueRequested("Breakpoints", &value);
QList<QVariant> list = value.toList(); QList<QVariant> list = value.toList();
clear(); clear();
foreach (const QVariant &var, list) { foreach (const QVariant &var, list) {
const QMap<QString, QVariant> map = var.toMap(); const QMap<QString, QVariant> map = var.toMap();
BreakpointData *data = new BreakpointData(this); BreakpointData *data = new BreakpointData(this);
data->fileName = map["filename"].toString(); QVariant v = map.value(QLatin1String("filename"));
data->lineNumber = map["linenumber"].toString(); if (v.isValid())
data->condition = map["condition"].toString(); data->fileName = v.toString();
data->ignoreCount = map["ignorecount"].toString(); v = map.value(QLatin1String("linenumber"));
data->funcName = map["funcname"].toString(); if (v.isValid())
data->enabled = !map["disabled"].toInt(); data->lineNumber = v.toString();
data->useFullPath = bool(map["usefullpath"].toInt()); v = map.value(QLatin1String("condition"));
if (v.isValid())
data->condition = v.toString();
v = map.value(QLatin1String("ignorecount"));
if (v.isValid())
data->ignoreCount = v.toInt();
v = map.value(QLatin1String("funcname"));
if (v.isValid())
data->funcName = v.toString();
v = map.value(QLatin1String("disabled"));
if (v.isValid())
data->enabled = !v.toInt();
v = map.value(QLatin1String("usefullpath"));
if (v.isValid())
data->useFullPath = bool(v.toInt());
data->markerFileName = data->fileName; data->markerFileName = data->fileName;
data->markerLineNumber = data->lineNumber.toInt(); data->markerLineNumber = data->lineNumber.toInt();
append(data); append(data);

View File

@@ -407,12 +407,19 @@ static bool setBreakPointEnabledById(CIDebugControl *ctl, unsigned long id, bool
return true; return true;
} }
static inline QString msgCannotSetBreakAtFunction(const QString &func, const QString &why)
{
return QString::fromLatin1("Cannot set a breakpoint at '%1': %2").arg(func, why);
}
// Synchronize (halted) engine breakpoints with those of the BreakHandler. // Synchronize (halted) engine breakpoints with those of the BreakHandler.
bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl, bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
CIDebugSymbols *syms, CIDebugSymbols *syms,
BreakHandler *handler, BreakHandler *handler,
QString *errorMessage) QString *errorMessage, QStringList *warnings)
{ {
errorMessage->clear();
warnings->clear();
// Do an initial check whether we are in a state that allows // Do an initial check whether we are in a state that allows
// for modifying breakPoints // for modifying breakPoints
ULONG engineCount; ULONG engineCount;
@@ -420,25 +427,29 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
*errorMessage = QString::fromLatin1("Cannot modify breakpoints: %1").arg(*errorMessage); *errorMessage = QString::fromLatin1("Cannot modify breakpoints: %1").arg(*errorMessage);
return false; return false;
} }
QString warning;
// Insert new ones // Insert new ones
bool updateMarkers = false; bool updateMarkers = false;
foreach (BreakpointData *nbd, handler->insertedBreakpoints()) { foreach (BreakpointData *nbd, handler->insertedBreakpoints()) {
warning.clear();
// Function breakpoints: Are the module names specified? // Function breakpoints: Are the module names specified?
bool breakPointOk = false; bool breakPointOk = false;
if (nbd->funcName.isEmpty()) { if (nbd->funcName.isEmpty()) {
breakPointOk = true; breakPointOk = true;
} else { } else {
switch (resolveSymbol(syms, &nbd->funcName, errorMessage)) { switch (resolveSymbol(syms, &nbd->funcName, &warning)) {
case ResolveSymbolOk: case ResolveSymbolOk:
breakPointOk = true; breakPointOk = true;
break; break;
case ResolveSymbolAmbiguous: case ResolveSymbolAmbiguous:
qWarning("Warning: %s\n", qPrintable(*errorMessage)); warnings->push_back(msgCannotSetBreakAtFunction(nbd->funcName, warning));
warning.clear();
breakPointOk = true; breakPointOk = true;
break; break;
case ResolveSymbolNotFound: case ResolveSymbolNotFound:
case ResolveSymbolError: case ResolveSymbolError:
qWarning("Warning: %s\n", qPrintable(*errorMessage)); warnings->push_back(msgCannotSetBreakAtFunction(nbd->funcName, warning));
warning.clear();
break; break;
}; };
} // function breakpoint } // function breakpoint
@@ -447,7 +458,7 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
quint64 address; quint64 address;
unsigned long id; unsigned long id;
CDBBreakPoint ncdbbp(*nbd); CDBBreakPoint ncdbbp(*nbd);
breakPointOk = ncdbbp.add(debugControl, &address, &id, errorMessage); breakPointOk = ncdbbp.add(debugControl, &address, &id, &warning);
if (breakPointOk) { if (breakPointOk) {
if (debugBP) if (debugBP)
qDebug() << "Added " << id << " at " << address << ncdbbp; qDebug() << "Added " << id << " at " << address << ncdbbp;
@@ -464,22 +475,21 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
nbd->bpFuncName = nbd->funcName; nbd->bpFuncName = nbd->funcName;
} }
} // had symbol } // had symbol
if (!breakPointOk) if (!breakPointOk && !warning.isEmpty())
qWarning("%s\n", qPrintable(*errorMessage)); warnings->push_back(warning); }
}
// Delete // Delete
foreach (BreakpointData *rbd, handler->takeRemovedBreakpoints()) { foreach (BreakpointData *rbd, handler->takeRemovedBreakpoints()) {
if (!removeBreakPointById(debugControl, rbd->bpNumber.toUInt(), errorMessage)) if (!removeBreakPointById(debugControl, rbd->bpNumber.toUInt(), &warning))
qWarning("%s\n", qPrintable(*errorMessage)); warnings->push_back(warning);
delete rbd; delete rbd;
} }
// Enable/Disable // Enable/Disable
foreach (BreakpointData *ebd, handler->takeEnabledBreakpoints()) foreach (BreakpointData *ebd, handler->takeEnabledBreakpoints())
if (!setBreakPointEnabledById(debugControl, ebd->bpNumber.toUInt(), true, errorMessage)) if (!setBreakPointEnabledById(debugControl, ebd->bpNumber.toUInt(), true, &warning))
qWarning("%s\n", qPrintable(*errorMessage)); warnings->push_back(warning);
foreach (BreakpointData *dbd, handler->takeDisabledBreakpoints()) foreach (BreakpointData *dbd, handler->takeDisabledBreakpoints())
if (!setBreakPointEnabledById(debugControl, dbd->bpNumber.toUInt(), false, errorMessage)) if (!setBreakPointEnabledById(debugControl, dbd->bpNumber.toUInt(), false, &warning))
qWarning("%s\n", qPrintable(*errorMessage)); warnings->push_back(warning);
if (updateMarkers) if (updateMarkers)
handler->updateMarkers(); handler->updateMarkers();

View File

@@ -73,7 +73,8 @@ struct CDBBreakPoint
static bool getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage); static bool getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
// Synchronize (halted) engine with BreakHandler. // Synchronize (halted) engine with BreakHandler.
static bool synchronizeBreakPoints(CIDebugControl* ctl, CIDebugSymbols *syms, static bool synchronizeBreakPoints(CIDebugControl* ctl, CIDebugSymbols *syms,
BreakHandler *bh, QString *errorMessage); BreakHandler *bh,
QString *errorMessage, QStringList *warnings);
// Return a 'canonical' file (using '/' and capitalized drive letter) // Return a 'canonical' file (using '/' and capitalized drive letter)
static QString canonicalSourceFile(const QString &f); static QString canonicalSourceFile(const QString &f);

View File

@@ -1182,6 +1182,8 @@ void CdbDebugEngine::selectThread(int index)
void CdbDebugEngine::attemptBreakpointSynchronization() void CdbDebugEngine::attemptBreakpointSynchronization()
{ {
if (!m_d->m_hDebuggeeProcess) // Sometimes called from the breakpoint Window
return;
QString errorMessage; QString errorMessage;
if (!m_d->attemptBreakpointSynchronization(&errorMessage)) if (!m_d->attemptBreakpointSynchronization(&errorMessage))
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
@@ -1215,10 +1217,15 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
return true; return true;
} }
return CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl, QStringList warnings;
const bool ok = CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl,
m_cif.debugSymbols, m_cif.debugSymbols,
m_debuggerManagerAccess->breakHandler(), m_debuggerManagerAccess->breakHandler(),
errorMessage); errorMessage, &warnings);
if (const int warningsCount = warnings.size())
for (int w = 0; w < warningsCount; w++)
m_engine->warning(warnings.at(w));
return ok;
} }
void CdbDebugEngine::reloadDisassembler() void CdbDebugEngine::reloadDisassembler()

View File

@@ -138,6 +138,7 @@ static ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol,
QStringList *matches, QStringList *matches,
QString *errorMessage) QString *errorMessage)
{ {
errorMessage->clear();
// Is it an incomplete symbol? // Is it an incomplete symbol?
if (symbol->contains(QLatin1Char('!'))) if (symbol->contains(QLatin1Char('!')))
return ResolveSymbolOk; return ResolveSymbolOk;