Commit 0b32820a authored by hjk's avatar hjk
Browse files

debugger: work on breakpoint enabling/disabling in gdb engine

parent a3923f8c
......@@ -489,8 +489,10 @@ void BreakHandler::setter(BreakpointId id, const type &value) \
Iterator it = m_storage.find(id); \
QTC_ASSERT(it != m_storage.end(), \
qDebug() << "ID" << id << "NOT KNOWN"; return); \
if (it->data.setter(value)) \
scheduleSynchronization(); \
if (!it->data.setter(value)) \
return; \
it->state = BreakpointChangeRequested; \
scheduleSynchronization(); \
}
#define PROPERTY(type, getter, setter) \
......@@ -524,6 +526,7 @@ void BreakHandler::setEnabled(BreakpointId id, bool on)
//qDebug() << "SET ENABLED: " << id << it->data.isEnabled() << on;
if (it->data.setEnabled(on)) {
it->destroyMarker();
it->state = BreakpointChangeRequested;
updateMarker(id);
scheduleSynchronization();
}
......@@ -579,6 +582,14 @@ void BreakHandler::ackIgnoreCount(BreakpointId id)
updateMarker(id);
}
void BreakHandler::ackEnabled(BreakpointId id)
{
Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return);
it->response.bpEnabled = it->data.isEnabled();
updateMarker(id);
}
Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
{
// switch (index.column()) {
......@@ -825,10 +836,11 @@ void BreakHandler::cleanupBreakpoint(BreakpointId id)
layoutChanged();
}
BreakpointResponse BreakHandler::response(BreakpointId id) const
const BreakpointResponse &BreakHandler::response(BreakpointId id) const
{
static BreakpointResponse dummy;
ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return BreakpointResponse());
QTC_ASSERT(it != m_storage.end(), return dummy);
return it->response;
}
......@@ -839,25 +851,6 @@ void BreakHandler::setResponse(BreakpointId id, const BreakpointResponse &data)
it->response = BreakpointResponse(data);
updateMarker(id);
}
#if 0
void BreakHandler::notifyBreakpointAdjusted(BreakpointId id)
{
QTC_ASSERT(state(id)== BreakpointChangeProceeding, /**/);
bp->bpNumber = rbp.bpNumber;
bp->bpCondition = rbp.bpCondition;
bp->bpIgnoreCount = rbp.bpIgnoreCount;
bp->bpFileName = rbp.bpFileName;
bp->bpFullName = rbp.bpFullName;
bp->bpLineNumber = rbp.bpLineNumber;
bp->bpCorrectedLineNumber = rbp.bpCorrectedLineNumber;
bp->bpThreadSpec = rbp.bpThreadSpec;
bp->bpFuncName = rbp.bpFuncName;
bp->bpAddress = rbp.bpAddress;
bp->bpMultiple = rbp.bpMultiple;
bp->bpEnabled = rbp.bpEnabled;
setState(id, BreakpointOk);
}
#endif
void BreakHandler::BreakpointItem::destroyMarker()
{
......
......@@ -124,13 +124,13 @@ public:
DebuggerEngine *engine(BreakpointId id) const;
void setEngine(BreakpointId id, DebuggerEngine *engine);
BreakpointResponse response(BreakpointId id) const;
const BreakpointResponse &response(BreakpointId id) const;
void setResponse(BreakpointId id, const BreakpointResponse &data);
// Incorporate debugger feedback. No synchronization request needed.
// Return true if something changed.
void ackCondition(BreakpointId id);
void ackIgnoreCount(BreakpointId id);
void ackEnabled(BreakpointId id);
void notifyBreakpointInsertOk(BreakpointId id);
void notifyBreakpointInsertFailed(BreakpointId id);
......
......@@ -124,13 +124,13 @@ bool BreakpointData::isLocatedAt(const QString &fileName, int lineNumber,
return lineNumber == line && fileNameMatch(fileName, m_markerFileName);
}
bool BreakpointData::conditionsMatch(const QString &other) const
bool BreakpointData::conditionsMatch(const QByteArray &other) const
{
// Some versions of gdb "beautify" the passed condition.
QString s1 = m_condition;
s1.remove(QChar(' '));
QString s2 = other;
s2.remove(QChar(' '));
QByteArray s1 = m_condition;
s1.replace(' ', "");
QByteArray s2 = other;
s2.replace(' ', "");
return s1 == s2;
}
......
......@@ -99,7 +99,7 @@ public:
bool isLocatedAt(const QString &fileName, int lineNumber,
bool useMarkerPosition) const;
bool conditionsMatch(const QString &other) const;
bool conditionsMatch(const QByteArray &other) const;
QString functionName() const { return m_functionName; }
QString markerFileName() const { return m_markerFileName; }
QString fileName() const { return m_fileName; }
......
......@@ -2297,9 +2297,20 @@ void GdbEngine::handleBreakList(const GdbMi &table)
void GdbEngine::handleBreakDisable(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
breakHandler()->updateMarkers();
}
QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
const BreakpointId id =response.cookie.toInt();
// This should only be the requested state.
QTC_ASSERT(!breakHandler()->isEnabled(id), /* Prevent later recursion */);
breakHandler()->ackEnabled(id);
}
void GdbEngine::handleBreakEnable(const GdbResponse &response)
{
QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
const BreakpointId id = response.cookie.toInt();
// This should only be the "wish" state.
QTC_ASSERT(breakHandler()->isEnabled(id), /* Prevent later recursion */);
breakHandler()->ackEnabled(id);
}
void GdbEngine::handleBreakIgnore(const GdbResponse &response)
......@@ -2314,35 +2325,30 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response)
// 29^done
//
// gdb 6.3 does not produce any console output
if (response.resultClass == GdbResultDone) {
QString msg = _(response.data.findChild("consolestreamoutput").data());
//if (msg.contains(__("Will stop next time breakpoint"))) {
// data->bpIgnoreCount = _("0");
//} else if (msg.contains(__("Will ignore next"))) {
// data->bpIgnoreCount = data->ignoreCount;
//}
// FIXME: this assumes it is doing the right thing...
breakHandler()->ackIgnoreCount(BreakpointId(response.cookie.toInt()));
}
QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
QString msg = _(response.data.findChild("consolestreamoutput").data());
//if (msg.contains(__("Will stop next time breakpoint")))
// data->bpIgnoreCount = _("0");
//else if (msg.contains(__("Will ignore next")))
// data->bpIgnoreCount = data->ignoreCount;
// FIXME: this assumes it is doing the right thing...
BreakpointId id(response.cookie.toInt());
// This should only be the "wish" state.
QTC_ASSERT(!breakHandler()->isEnabled(id), /* prevent later recursion */);
breakHandler()->ackEnabled(id);
}
void GdbEngine::handleBreakCondition(const GdbResponse &response)
{
const int id = response.cookie.toInt();
if (response.resultClass == GdbResultDone) {
// We just assume it was successful. Otherwise we had to parse
// the output stream data.
//qDebug() << "HANDLE BREAK CONDITION" << bpNumber << data->condition;
breakHandler()->ackCondition(id);
} else {
QByteArray msg = response.data.findChild("msg").data();
// happens on Mac
if (1 || msg.startsWith("Error parsing breakpoint condition. "
" Will try again when we hit the breakpoint.")) {
//qDebug() << "ERROR BREAK CONDITION" << bpNumber << data->condition;
breakHandler()->ackCondition(id);
}
}
QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
const BreakpointId id = response.cookie.toInt();
// We just assume it was successful. Otherwise we had to parse
// the output stream data.
// The following happens on Mac:
// QByteArray msg = response.data.findChild("msg").data();
// if (1 || msg.startsWith("Error parsing breakpoint condition. "
// " Will try again when we hit the breakpoint.")) {
breakHandler()->ackCondition(id);
}
void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
......@@ -2607,9 +2613,63 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
CB(handleBreakInsert1), id);
}
void GdbEngine::changeBreakpoint(BreakpointId)
void GdbEngine::changeBreakpoint(BreakpointId id)
{
QTC_ASSERT(false, return);
const BreakpointData *data0 = breakHandler()->breakpointById(id);
QTC_ASSERT(data0, return);
const BreakpointData &data = *data0;
const BreakpointResponse &response = breakHandler()->response(id);
QTC_ASSERT(response.bpNumber > 0, return);
const QByteArray bpnr = QByteArray::number(response.bpNumber);
if (data.condition() != response.bpCondition
&& !data.conditionsMatch(response.bpCondition)) {
// Update conditions if needed.
postCommand("condition " + bpnr + ' ' + data.condition(),
NeedsStop | RebuildBreakpointModel,
CB(handleBreakCondition), id);
}
if (data.ignoreCount() != response.bpIgnoreCount) {
// Update ignorecount if needed.
postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount()),
NeedsStop | RebuildBreakpointModel,
CB(handleBreakIgnore), id);
}
if (!data.isEnabled() && response.bpEnabled) {
postCommand("-break-disable " + bpnr,
NeedsStop | RebuildBreakpointModel,
CB(handleBreakDisable), id);
}
if (data.isEnabled() && !response.bpEnabled) {
postCommand("-break-enable " + bpnr,
NeedsStop | RebuildBreakpointModel,
CB(handleBreakEnable), id);
}
/*
if (data.threadSpec() != response.bpThreadSpec)
// The only way to change this seems to be to re-set the bp completely.
//qDebug() << "FIXME: THREAD: " << data.threadSpec << response.bpThreadSpec;
FIXME
data.setThreadSpec.clear();
postCommand("-break-delete " + bpnr,
NeedsStop | RebuildBreakpointModel);
sendInsertBreakpoint(index);
continue;
}
*/
/*
if (data->bpAddress && data->bpCorrectedLineNumber == 0) {
// Prevent endless loop.
data->bpCorrectedLineNumber = -1;
if (debuggerCore()->boolSetting(AdjustBreakpointLocations)) {
postCommand(
"info line *0x" + QByteArray::number(data->bpAddress, 16),
NeedsStop | RebuildBreakpointModel,
CB(handleInfoLine), id)
}
}
*/
}
void GdbEngine::removeBreakpoint(BreakpointId id)
......
......@@ -354,6 +354,7 @@ private: ////////// View & Data Stuff //////////
void handleBreakList(const GdbMi &table);
void handleBreakIgnore(const GdbResponse &response);
void handleBreakDisable(const GdbResponse &response);
void handleBreakEnable(const GdbResponse &response);
void handleBreakInsert1(const GdbResponse &response);
void handleBreakInsert2(const GdbResponse &response);
void handleBreakCondition(const GdbResponse &response);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment