forked from qt-creator/qt-creator
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:
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user