Commit 16fe6734 authored by hjk's avatar hjk Committed by hjk

debugger: improve handling of subbreakpoints in gdb 7.2 and earlier

Change-Id: I6cd4c2a07544ea902798e2e4596bd56e634f15e3
Reviewed-on: http://codereview.qt.nokia.com/746Reviewed-by: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent c0412867
......@@ -773,6 +773,13 @@ bool BreakHandler::isTracepoint(BreakpointModelId id) const
return it->data.tracepoint;
}
bool BreakHandler::needsChildren(BreakpointModelId id) const
{
ConstIterator it = m_storage.find(id);
BREAK_ASSERT(it != m_storage.end(), return false);
return it->response.multiple && it->subItems.isEmpty();
}
void BreakHandler::setTracepoint(BreakpointModelId id, bool on)
{
Iterator it = m_storage.find(id);
......@@ -1045,11 +1052,11 @@ void BreakHandler::appendBreakpoint(const BreakpointParameters &data)
scheduleSynchronization();
}
void BreakHandler::handleAlienBreakpoint(const BreakpointResponse &response,
DebuggerEngine *engine)
void BreakHandler::handleAlienBreakpoint(BreakpointModelId id,
const BreakpointResponse &response, DebuggerEngine *engine)
{
if (response.id.isMinor()) {
insertSubBreakpoint(response);
insertSubBreakpoint(id, response);
} else {
BreakpointParameters data = response;
data.type = BreakpointByFileAndLine;
......@@ -1094,15 +1101,15 @@ int BreakHandler::indexOf(BreakpointModelId id) const
return -1;
}
void BreakHandler::insertSubBreakpoint(const BreakpointResponse &data)
void BreakHandler::insertSubBreakpoint(BreakpointModelId id,
const BreakpointResponse &data)
{
BreakpointResponseId id = data.id;
QTC_ASSERT(id.isMinor(), return);
BreakpointModelId modelId = findBreakpointByResponseId(id.parent());
Iterator it = m_storage.find(modelId);
QTC_ASSERT(data.id.isMinor(), return);
QTC_ASSERT(id.isMajor(), return);
Iterator it = m_storage.find(id);
if (it == m_storage.end()) {
qDebug() << "FAILED: " << id.toString() << modelId.toString();
qDebug() << "FAILED: " << id.toString();
for (ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
it != et; ++it) {
qDebug() << " ID: " << it->response.id.toString();
......@@ -1112,7 +1119,7 @@ void BreakHandler::insertSubBreakpoint(const BreakpointResponse &data)
}
QTC_ASSERT(it != m_storage.end(), return);
int minorPart = id.minorPart();
int minorPart = data.id.minorPart();
int pos = -1;
for (int i = 0; i != it->subItems.size(); ++i) {
if (it->subItems.at(i).id.minorPart() == minorPart) {
......@@ -1122,7 +1129,8 @@ void BreakHandler::insertSubBreakpoint(const BreakpointResponse &data)
}
if (pos == -1) {
// This is a new sub-breakpoint.
int row = indexOf(modelId);
//qDebug() << "NEW ID" << id;
int row = indexOf(id);
QTC_ASSERT(row != -1, return);
QModelIndex idx = createIndex(row, 0, id.toInternalId());
beginInsertRows(idx, it->subItems.size(), it->subItems.size());
......@@ -1130,6 +1138,7 @@ void BreakHandler::insertSubBreakpoint(const BreakpointResponse &data)
endInsertRows();
} else {
// This modifies an existing sub-breakpoint.
//qDebug() << "EXISTING ID" << id;
it->subItems[pos] = data;
layoutChanged();
}
......@@ -1269,8 +1278,8 @@ const BreakpointResponse &BreakHandler::response(BreakpointModelId id) const
{
static BreakpointResponse dummy;
ConstIterator it = m_storage.find(id);
BREAK_ASSERT(it != m_storage.end(),
qDebug() << "NO RESPONSE FOR " << id; return dummy);
//BREAK_ASSERT(it != m_storage.end(),
// qDebug() << "NO RESPONSE FOR " << id; return dummy);
if (it == m_storage.end())
return dummy;
return it->response;
......
......@@ -70,9 +70,9 @@ public:
// The only way to add a new breakpoint.
void appendBreakpoint(const BreakpointParameters &data);
void handleAlienBreakpoint(const BreakpointResponse &response,
DebuggerEngine *engine);
void insertSubBreakpoint(const BreakpointResponse &data);
void handleAlienBreakpoint(BreakpointModelId id,
const BreakpointResponse &response, DebuggerEngine *engine);
void insertSubBreakpoint(BreakpointModelId id, const BreakpointResponse &data);
void removeAlienBreakpoint(BreakpointModelId id);
BreakpointModelIds allBreakpointIds() const;
......@@ -143,6 +143,7 @@ public:
const BreakpointResponse &response(BreakpointModelId id) const;
void setResponse(BreakpointModelId id, const BreakpointResponse &data);
bool needsChange(BreakpointModelId id) const;
bool needsChildren(BreakpointModelId id) const;
// State transitions.
void notifyBreakpointChangeAfterInsertNeeded(BreakpointModelId id);
......
......@@ -493,7 +493,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
result = GdbMi();
result.fromString(ba);
BreakHandler *handler = breakHandler();
BreakpointModelId id = BreakpointModelId(-1);
BreakpointModelId id;
BreakpointResponse br;
foreach (const GdbMi &bkpt, result.children()) {
const QByteArray nr = bkpt.findChild("number").data();
......@@ -505,31 +505,31 @@ void GdbEngine::handleResponse(const QByteArray &buff)
updateResponse(sub, bkpt);
sub.id = rid;
sub.type = br.type;
handler->insertSubBreakpoint(sub);
handler->insertSubBreakpoint(id, sub);
} else {
// A primary breakpoint.
BreakpointModelId id =
handler->findBreakpointByResponseId(rid);
id = handler->findBreakpointByResponseId(rid);
//qDebug() << "NR: " << nr << "RID: " << rid
// << "ID: " << id;
//BreakpointModelId id =
// handler->findBreakpointByResponseId(rid);
br = handler->response(id);
updateResponse(br, bkpt);
handler->setResponse(id, br);
}
}
}
if (!isQmlStepBreakpoint(br.id)) {
handler->setResponse(id, br);
attemptAdjustBreakpointLocation(id);
}
m_hasBreakpointNotifications = true;
} else if (asyncClass == "breakpoint-created") {
// "{bkpt={number="1",type="breakpoint",disp="del",enabled="y",
// addr="<PENDING>",pending="main",times="0",
//original-location="main"}}"
BreakHandler *handler = breakHandler();
foreach (const GdbMi &bkpt, result.children()) {
QByteArray nr = bkpt.findChild("number").data();
BreakpointResponse br;
updateResponse(br, bkpt);
br.id = BreakpointResponseId(nr);
breakHandler()->handleAlienBreakpoint(br, this);
BreakpointModelId id = handler->findBreakpointByResponseId(br.id);
handler->handleAlienBreakpoint(id, br, this);
}
} else if (asyncClass == "breakpoint-deleted") {
// "breakpoint-deleted" "{id="1"}"
......@@ -2504,22 +2504,40 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response)
BreakHandler *handler = breakHandler();
BreakpointModelId id = response.cookie.value<BreakpointModelId>();
if (response.resultClass == GdbResultDone) {
// Interesting only on Mac?
GdbMi bkpt = response.data.findChild("bkpt");
BreakpointResponse br = handler->response(id);
updateResponse(br, bkpt);
handler->setResponse(id, br);
if (handler->needsChange(id)) {
handler->notifyBreakpointChangeAfterInsertNeeded(id);
changeBreakpoint(id);
} else {
handler->notifyBreakpointInsertOk(id);
const GdbMi bkpt = response.data.findChild("bkpt");
const BreakpointResponseId rid(bkpt.findChild("number").data());
if (!isHiddenBreakpoint(rid)) {
BreakpointResponse br = handler->response(id);
foreach (const GdbMi bkpt, response.data.children()) {
QByteArray nr = bkpt.findChild("number").data();
BreakpointResponseId rid(nr);
if (nr.contains('.')) {
// A sub-breakpoint.
BreakpointResponse sub;
updateResponse(sub, bkpt);
sub.id = rid;
sub.type = br.type;
handler->insertSubBreakpoint(id, sub);
} else {
// A primary breakpoint.
updateResponse(br, bkpt);
br.id = rid;
handler->setResponse(id, br);
}
}
if (handler->needsChange(id)) {
handler->notifyBreakpointChangeAfterInsertNeeded(id);
changeBreakpoint(id);
} else {
handler->notifyBreakpointInsertOk(id);
}
br = handler->response(id);
attemptAdjustBreakpointLocation(id);
// Remove if we only support 7.4 or later.
if (br.multiple && !m_hasBreakpointNotifications)
postCommand("info break " + QByteArray::number(br.id.majorPart()),
NeedsStop, CB(handleBreakListMultiple), QVariant::fromValue(id));
}
br = handler->response(id);
attemptAdjustBreakpointLocation(id);
if (br.multiple)
postCommand("info break " + QByteArray::number(br.id.majorPart()),
NeedsStop, CB(handleBreakListMultiple), QVariant::fromValue(id));
} else if (response.data.findChild("msg").data().contains("Unknown option")) {
// Older version of gdb don't know the -a option to set tracepoints
// ^error,msg="mi_cmd_break_insert: Unknown option ``a''"
......@@ -2827,7 +2845,7 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointModelI
sub.id = subId;
sub.type = response.type;
sub.address = address;
handler->insertSubBreakpoint(sub);
handler->insertSubBreakpoint(id, sub);
location.clear();
function.clear();
address = 0;
......@@ -2963,6 +2981,7 @@ void GdbEngine::changeBreakpoint(BreakpointModelId id)
QTC_ASSERT(data.type != UnknownType, return);
const BreakpointResponse &response = handler->response(id);
QTC_ASSERT(response.id.isValid(), return);
qDebug() << "DELETING: " << response.id;
const QByteArray bpnr = response.id.toByteArray();
const BreakpointState state = handler->state(id);
if (state == BreakpointChangeRequested)
......
......@@ -494,6 +494,7 @@ private: ////////// View & Data Stuff //////////
//
void handleBreakList(const GdbResponse &response);
void handleBreakList(const GdbMi &table);
void handleBreakModifications(const GdbMi &bkpts);
void handleBreakListMultiple(const GdbResponse &response);
void handleBreakIgnore(const GdbResponse &response);
void handleBreakDisable(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