forked from qt-creator/qt-creator
debugger: handle results of manual break commands
Change-Id: I0ab8ad3ef3ddfe7c8d69fd163864875190698475 Reviewed-on: http://codereview.qt.nokia.com/744 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -990,6 +990,14 @@ void BreakHandler::notifyBreakpointNeedsReinsertion(BreakpointId id)
|
|||||||
it->state = BreakpointInsertRequested;
|
it->state = BreakpointInsertRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BreakHandler::removeAlienBreakpoint(BreakpointId id)
|
||||||
|
{
|
||||||
|
Iterator it = m_storage.find(id);
|
||||||
|
BREAK_ASSERT(it != m_storage.end(), return);
|
||||||
|
it->state = BreakpointDead;
|
||||||
|
cleanupBreakpoint(id);
|
||||||
|
}
|
||||||
|
|
||||||
void BreakHandler::removeBreakpoint(BreakpointId id)
|
void BreakHandler::removeBreakpoint(BreakpointId id)
|
||||||
{
|
{
|
||||||
Iterator it = m_storage.find(id);
|
Iterator it = m_storage.find(id);
|
||||||
@@ -1011,14 +1019,13 @@ void BreakHandler::removeBreakpoint(BreakpointId id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ok to be not thread-safe. The order does not matter and only the gui
|
||||||
|
// produces authoritative ids.
|
||||||
|
static int currentId = 0;
|
||||||
|
|
||||||
void BreakHandler::appendBreakpoint(const BreakpointParameters &data)
|
void BreakHandler::appendBreakpoint(const BreakpointParameters &data)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(data.type != UnknownType, return);
|
QTC_ASSERT(data.type != UnknownType, return);
|
||||||
|
|
||||||
// Ok to be not thread-safe. The order does not matter and only the gui
|
|
||||||
// produces authoritative ids.
|
|
||||||
static quint64 currentId = 0;
|
|
||||||
|
|
||||||
BreakpointId id(++currentId);
|
BreakpointId id(++currentId);
|
||||||
BreakpointItem item;
|
BreakpointItem item;
|
||||||
item.data = data;
|
item.data = data;
|
||||||
@@ -1036,6 +1043,35 @@ void BreakHandler::appendBreakpoint(const BreakpointParameters &data)
|
|||||||
scheduleSynchronization();
|
scheduleSynchronization();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BreakHandler::handleAlienBreakpoint(const BreakpointResponse &response,
|
||||||
|
DebuggerEngine *engine)
|
||||||
|
{
|
||||||
|
if (response.id.isMinor()) {
|
||||||
|
insertSubBreakpoint(response);
|
||||||
|
} else {
|
||||||
|
BreakpointParameters data = response;
|
||||||
|
data.type = BreakpointByFileAndLine;
|
||||||
|
data.functionName.clear();
|
||||||
|
|
||||||
|
BreakpointId id(++currentId);
|
||||||
|
BreakpointItem item;
|
||||||
|
item.data = data;
|
||||||
|
item.response = response;
|
||||||
|
item.state = BreakpointInserted;
|
||||||
|
item.engine = engine;
|
||||||
|
|
||||||
|
const int row = m_storage.size();
|
||||||
|
beginInsertRows(QModelIndex(), row, row);
|
||||||
|
m_storage.insert(id, item);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
layoutChanged();
|
||||||
|
|
||||||
|
updateMarker(id);
|
||||||
|
scheduleSynchronization();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BreakpointId BreakHandler::at(int n) const
|
BreakpointId BreakHandler::at(int n) const
|
||||||
{
|
{
|
||||||
if (n < 0 || n >= m_storage.size())
|
if (n < 0 || n >= m_storage.size())
|
||||||
@@ -1062,6 +1098,17 @@ void BreakHandler::insertSubBreakpoint(const BreakpointResponse &data)
|
|||||||
QTC_ASSERT(id.isMinor(), return);
|
QTC_ASSERT(id.isMinor(), return);
|
||||||
BreakpointId majorId = id.parent();
|
BreakpointId majorId = id.parent();
|
||||||
Iterator it = m_storage.find(majorId);
|
Iterator it = m_storage.find(majorId);
|
||||||
|
|
||||||
|
if (it == m_storage.end()) {
|
||||||
|
qDebug() << "FAILED: " << id.toString() << majorId.toString();
|
||||||
|
for (ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
|
||||||
|
it != et; ++it) {
|
||||||
|
qDebug() << " ID: " << it->response.id.toString();
|
||||||
|
qDebug() << " DATA: " << it->data.toString();
|
||||||
|
qDebug() << " RESP: " << it->response.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QTC_ASSERT(it != m_storage.end(), return);
|
QTC_ASSERT(it != m_storage.end(), return);
|
||||||
int row = indexOf(majorId);
|
int row = indexOf(majorId);
|
||||||
QTC_ASSERT(row != -1, return);
|
QTC_ASSERT(row != -1, return);
|
||||||
@@ -1094,6 +1141,7 @@ void BreakHandler::saveSessionData()
|
|||||||
void BreakHandler::loadSessionData()
|
void BreakHandler::loadSessionData()
|
||||||
{
|
{
|
||||||
m_storage.clear();
|
m_storage.clear();
|
||||||
|
reset();
|
||||||
loadBreakpoints();
|
loadBreakpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,7 +1151,7 @@ void BreakHandler::removeSessionData()
|
|||||||
for ( ; it != et; ++it)
|
for ( ; it != et; ++it)
|
||||||
it->destroyMarker();
|
it->destroyMarker();
|
||||||
m_storage.clear();
|
m_storage.clear();
|
||||||
layoutChanged();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BreakHandler::breakByFunction(const QString &functionName)
|
void BreakHandler::breakByFunction(const QString &functionName)
|
||||||
|
|||||||
@@ -70,7 +70,10 @@ public:
|
|||||||
|
|
||||||
// The only way to add a new breakpoint.
|
// The only way to add a new breakpoint.
|
||||||
void appendBreakpoint(const BreakpointParameters &data);
|
void appendBreakpoint(const BreakpointParameters &data);
|
||||||
|
void handleAlienBreakpoint(const BreakpointResponse &response,
|
||||||
|
DebuggerEngine *engine);
|
||||||
void insertSubBreakpoint(const BreakpointResponse &data);
|
void insertSubBreakpoint(const BreakpointResponse &data);
|
||||||
|
void removeAlienBreakpoint(BreakpointId id);
|
||||||
|
|
||||||
BreakpointIds allBreakpointIds() const;
|
BreakpointIds allBreakpointIds() const;
|
||||||
BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const;
|
BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const;
|
||||||
|
|||||||
@@ -164,6 +164,15 @@ bool BreakpointParameters::conditionsMatch(const QByteArray &other) const
|
|||||||
return s1 == s2;
|
return s1 == s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BreakpointParameters::setLocation(const QByteArray &location)
|
||||||
|
{
|
||||||
|
if (location.size()) {
|
||||||
|
int pos = location.indexOf(':');
|
||||||
|
lineNumber = location.mid(pos + 1).toInt();
|
||||||
|
fileName = QString::fromUtf8(location.left(pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString BreakpointParameters::toString() const
|
QString BreakpointParameters::toString() const
|
||||||
{
|
{
|
||||||
QString result;
|
QString result;
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ public:
|
|||||||
bool isBreakpoint() const { return !isWatchpoint() && !isTracepoint(); }
|
bool isBreakpoint() const { return !isWatchpoint() && !isTracepoint(); }
|
||||||
bool isTracepoint() const { return tracepoint; }
|
bool isTracepoint() const { return tracepoint; }
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
void setLocation(const QByteArray &location); // file.cpp:42
|
||||||
|
|
||||||
bool operator==(const BreakpointParameters &p) const { return equals(p); }
|
bool operator==(const BreakpointParameters &p) const { return equals(p); }
|
||||||
bool operator!=(const BreakpointParameters &p) const { return !equals(p); }
|
bool operator!=(const BreakpointParameters &p) const { return !equals(p); }
|
||||||
|
|||||||
@@ -518,6 +518,26 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
|||||||
attemptAdjustBreakpointLocation(id);
|
attemptAdjustBreakpointLocation(id);
|
||||||
}
|
}
|
||||||
m_hasBreakpointNotifications = true;
|
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"}}"
|
||||||
|
foreach (const GdbMi &bkpt, result.children()) {
|
||||||
|
QByteArray nr = bkpt.findChild("number").data();
|
||||||
|
BreakpointResponse br;
|
||||||
|
updateResponse(br, bkpt);
|
||||||
|
br.id = BreakpointId(nr);
|
||||||
|
qDebug() << "NR: " << nr << " ID: " << br.id.toString();
|
||||||
|
breakHandler()->handleAlienBreakpoint(br, this);
|
||||||
|
}
|
||||||
|
} else if (asyncClass == "breakpoint-deleted") {
|
||||||
|
// "breakpoint-deleted" "{id="1"}"
|
||||||
|
// New in FSF gdb since 2011-04-27.
|
||||||
|
BreakHandler *handler = breakHandler();
|
||||||
|
QByteArray nr = result.findChild("id").data();
|
||||||
|
BreakpointId id = handler->findBreakpointByNumber(nr.toInt());
|
||||||
|
if (id.isValid())
|
||||||
|
handler->removeAlienBreakpoint(id);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "IGNORED ASYNC OUTPUT"
|
qDebug() << "IGNORED ASYNC OUTPUT"
|
||||||
<< asyncClass << result.toString();
|
<< asyncClass << result.toString();
|
||||||
@@ -838,7 +858,7 @@ void GdbEngine::flushQueuedCommands()
|
|||||||
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
|
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
|
||||||
GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
|
GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
|
||||||
showMessage(_("RUNNING QUEUED COMMAND " + cmd.command + ' '
|
showMessage(_("RUNNING QUEUED COMMAND " + cmd.command + ' '
|
||||||
+ cmd.callbackName));
|
+ (cmd.callbackName ? cmd.callbackName : "<unnamed callback>")));
|
||||||
flushCommand(cmd);
|
flushCommand(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2286,6 +2306,8 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(bkpt.isValid(), return);
|
QTC_ASSERT(bkpt.isValid(), return);
|
||||||
|
|
||||||
|
QByteArray originalLocation;
|
||||||
|
|
||||||
response.multiple = false;
|
response.multiple = false;
|
||||||
response.enabled = true;
|
response.enabled = true;
|
||||||
response.pending = false;
|
response.pending = false;
|
||||||
@@ -2341,6 +2363,8 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt)
|
|||||||
response.tracepoint = true;
|
response.tracepoint = true;
|
||||||
else if (!child.data().contains("reakpoint"))
|
else if (!child.data().contains("reakpoint"))
|
||||||
response.type = WatchpointAtAddress;
|
response.type = WatchpointAtAddress;
|
||||||
|
} else if (child.hasName("original-location")) {
|
||||||
|
originalLocation = child.data();
|
||||||
}
|
}
|
||||||
// This field is not present. Contents needs to be parsed from
|
// This field is not present. Contents needs to be parsed from
|
||||||
// the plain "ignore" response.
|
// the plain "ignore" response.
|
||||||
@@ -2361,6 +2385,9 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt)
|
|||||||
}
|
}
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
response.fileName = name;
|
response.fileName = name;
|
||||||
|
|
||||||
|
if (name.isEmpty())
|
||||||
|
response.setLocation(originalLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GdbEngine::breakLocation(const QString &file) const
|
QString GdbEngine::breakLocation(const QString &file) const
|
||||||
@@ -2797,11 +2824,7 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
|
|||||||
BreakpointResponse sub;
|
BreakpointResponse sub;
|
||||||
sub.address = address;
|
sub.address = address;
|
||||||
sub.functionName = QString::fromUtf8(function);
|
sub.functionName = QString::fromUtf8(function);
|
||||||
if (location.size()) {
|
sub.setLocation(location);
|
||||||
int pos = location.indexOf(':');
|
|
||||||
sub.lineNumber = location.mid(pos + 1).toInt();
|
|
||||||
sub.fileName = QString::fromUtf8(location.left(pos));
|
|
||||||
}
|
|
||||||
sub.id = subId;
|
sub.id = subId;
|
||||||
sub.type = response.type;
|
sub.type = response.type;
|
||||||
sub.address = address;
|
sub.address = address;
|
||||||
|
|||||||
Reference in New Issue
Block a user