forked from qt-creator/qt-creator
debugger: enable modification of std::string and QString
This commit is contained in:
@@ -1015,6 +1015,9 @@ qqFormats = {}
|
|||||||
# This is a cache of all known dumpers.
|
# This is a cache of all known dumpers.
|
||||||
qqDumpers = {}
|
qqDumpers = {}
|
||||||
|
|
||||||
|
# This is a cache of all dumpers that support writing.
|
||||||
|
qqEditable = {}
|
||||||
|
|
||||||
# This is a cache of the namespace of the currently used Qt version.
|
# This is a cache of the namespace of the currently used Qt version.
|
||||||
# FIXME: This is not available on 'bbsetup' time, only at 'bb' time.
|
# FIXME: This is not available on 'bbsetup' time, only at 'bb' time.
|
||||||
|
|
||||||
@@ -1049,16 +1052,55 @@ def bbsetup():
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
qqFormats[name] = formats
|
qqFormats[name] = formats
|
||||||
|
elif key.startswith("qedit__"):
|
||||||
|
name = key[7:]
|
||||||
|
try:
|
||||||
|
qqEditable[name] = value
|
||||||
|
except:
|
||||||
|
pass
|
||||||
result = "dumpers=["
|
result = "dumpers=["
|
||||||
#qqNs = qtNamespace() # This is too early
|
#qqNs = qtNamespace() # This is too early
|
||||||
for key, value in qqFormats.items():
|
for key, value in qqFormats.items():
|
||||||
result += '{type="%s",formats="%s"},' % (key, value)
|
if qqEditable.has_key(key):
|
||||||
|
result += '{type="%s",formats="%s",editable="true"},' % (key, value)
|
||||||
|
else:
|
||||||
|
result += '{type="%s",formats="%s"},' % (key, value)
|
||||||
result += ']'
|
result += ']'
|
||||||
#result += ',namespace="%s"' % qqNs
|
#result += ',namespace="%s"' % qqNs
|
||||||
result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList())
|
result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
#
|
||||||
|
# Edit Command
|
||||||
|
#
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
def bbedit(args):
|
||||||
|
(type, expr, value) = args.split(" ")
|
||||||
|
type = base64.b64decode(type)
|
||||||
|
ns = qtNamespace()
|
||||||
|
type = type[len(ns):]
|
||||||
|
type = type.replace("::", "__")
|
||||||
|
expr = base64.b64decode(expr)
|
||||||
|
value = base64.b64decode(value)
|
||||||
|
if qqEditable.has_key(type):
|
||||||
|
qqEditable[type](expr, value)
|
||||||
|
warn("EDIT: %s %s %s: " % (type, expr, value))
|
||||||
|
|
||||||
|
class EditCommand(gdb.Command):
|
||||||
|
"""QtCreator Data Edit Support"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(EditCommand, self).__init__("bbedit", gdb.COMMAND_OBSCURE)
|
||||||
|
|
||||||
|
def invoke(self, args, from_tty):
|
||||||
|
bbedit(args)
|
||||||
|
|
||||||
|
EditCommand()
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
#
|
#
|
||||||
# FrameCommand
|
# FrameCommand
|
||||||
|
@@ -1354,6 +1354,18 @@ def qdump__QStandardItem(d, item):
|
|||||||
d.putPlainChildren(item)
|
d.putPlainChildren(item)
|
||||||
|
|
||||||
|
|
||||||
|
def qedit__QString(expr, value):
|
||||||
|
cmd = "call (%s).resize(%d)" % (expr, len(value))
|
||||||
|
gdb.execute(cmd)
|
||||||
|
d = gdb.parse_and_eval(expr)["d"]["data"]
|
||||||
|
cmd = "set {short[%d]}%s={" % (len(value), long(d))
|
||||||
|
for i in range(len(value)):
|
||||||
|
if i != 0:
|
||||||
|
cmd += ','
|
||||||
|
cmd += str(ord(value[i]))
|
||||||
|
cmd += '}'
|
||||||
|
gdb.execute(cmd)
|
||||||
|
|
||||||
def qform__QString():
|
def qform__QString():
|
||||||
return "Inline,Separate Window"
|
return "Inline,Separate Window"
|
||||||
|
|
||||||
@@ -1925,6 +1937,13 @@ def qdump__std__vector(d, item):
|
|||||||
p += 1
|
p += 1
|
||||||
|
|
||||||
|
|
||||||
|
def qedit__std__string(expr, value):
|
||||||
|
cmd = "print (%s).assign(\"%s\")" % (expr, value)
|
||||||
|
gdb.execute(cmd)
|
||||||
|
|
||||||
|
def qedit__string(expr, value):
|
||||||
|
qdump__std__string(expr, value)
|
||||||
|
|
||||||
def qdump__string(d, item):
|
def qdump__string(d, item):
|
||||||
qdump__std__string(d, item)
|
qdump__std__string(d, item)
|
||||||
|
|
||||||
|
@@ -2199,11 +2199,9 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp
|
|||||||
// is called <MULTIPLE>.
|
// is called <MULTIPLE>.
|
||||||
//qDebug() << "ADDR: " << child.data() << (child.data() == "<MULTIPLE>");
|
//qDebug() << "ADDR: " << child.data() << (child.data() == "<MULTIPLE>");
|
||||||
if (child.data().startsWith("0x")) {
|
if (child.data().startsWith("0x")) {
|
||||||
response.address = child.data().mid(2).toULongLong(0, 16);
|
response.address = child.toAddress();
|
||||||
} else {
|
} else {
|
||||||
response.extra = child.data();
|
response.extra = child.data();
|
||||||
if (child.data() == "<MULTIPLE>")
|
|
||||||
response.multiple = true;
|
|
||||||
}
|
}
|
||||||
} else if (child.hasName("file")) {
|
} else if (child.hasName("file")) {
|
||||||
file = child.data();
|
file = child.data();
|
||||||
@@ -2320,7 +2318,7 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
|
|||||||
// Mac yields:
|
// Mac yields:
|
||||||
//>32^done,wpt={number="4",exp="*4355182176"}
|
//>32^done,wpt={number="4",exp="*4355182176"}
|
||||||
bresponse.number = wpt.findChild("number").data().toInt();
|
bresponse.number = wpt.findChild("number").data().toInt();
|
||||||
bresponse.address = wpt.findChild("exp").data().toULongLong(0, 0);
|
bresponse.address = wpt.findChild("exp").toAddress();
|
||||||
handler->setResponse(id, bresponse);
|
handler->setResponse(id, bresponse);
|
||||||
QTC_ASSERT(!handler->needsChange(id), /**/);
|
QTC_ASSERT(!handler->needsChange(id), /**/);
|
||||||
handler->notifyBreakpointInsertOk(id);
|
handler->notifyBreakpointInsertOk(id);
|
||||||
@@ -3147,7 +3145,7 @@ StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level)
|
|||||||
frame.function = _(frameMi.findChild("func").data());
|
frame.function = _(frameMi.findChild("func").data());
|
||||||
frame.from = _(frameMi.findChild("from").data());
|
frame.from = _(frameMi.findChild("from").data());
|
||||||
frame.line = frameMi.findChild("line").data().toInt();
|
frame.line = frameMi.findChild("line").data().toInt();
|
||||||
frame.address = frameMi.findChild("addr").data().toULongLong(0, 16);
|
frame.address = frameMi.findChild("addr").toAddress();
|
||||||
frame.usable = QFileInfo(frame.file).isReadable();
|
frame.usable = QFileInfo(frame.file).isReadable();
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
@@ -3902,13 +3900,22 @@ void GdbEngine::insertData(const WatchData &data0)
|
|||||||
watchHandler()->insertData(data);
|
watchHandler()->insertData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::assignValueInDebugger(const WatchData *,
|
void GdbEngine::assignValueInDebugger(const WatchData *data,
|
||||||
const QString &expression, const QVariant &value)
|
const QString &expression, const QVariant &value)
|
||||||
{
|
{
|
||||||
postCommand("-var-delete assign");
|
if (hasPython()) {
|
||||||
postCommand("-var-create assign * " + expression.toLatin1());
|
QByteArray cmd = "bbedit "
|
||||||
postCommand("-var-assign assign " + GdbMi::escapeCString(value.toString().toLatin1()),
|
+ data->type.toBase64() + ' '
|
||||||
Discardable, CB(handleVarAssign));
|
+ expression.toUtf8().toBase64() + ' '
|
||||||
|
+ value.toString().toUtf8().toBase64();
|
||||||
|
postCommand(cmd, Discardable, CB(handleVarAssign));
|
||||||
|
} else {
|
||||||
|
postCommand("-var-delete assign");
|
||||||
|
postCommand("-var-create assign * " + expression.toLatin1());
|
||||||
|
postCommand("-var-assign assign " +
|
||||||
|
GdbMi::escapeCString(value.toString().toLatin1()),
|
||||||
|
Discardable, CB(handleVarAssign));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::watchPoint(const QPoint &pnt)
|
void GdbEngine::watchPoint(const QPoint &pnt)
|
||||||
|
@@ -373,6 +373,16 @@ GdbMi GdbMi::findChild(const char *name) const
|
|||||||
return GdbMi();
|
return GdbMi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qulonglong GdbMi::toAddress() const
|
||||||
|
{
|
||||||
|
QByteArray ba = m_data;
|
||||||
|
if (ba.endsWith('L'))
|
||||||
|
ba.chop(1);
|
||||||
|
if (ba.startsWith('*') || ba.startsWith('@'))
|
||||||
|
ba = ba.mid(1);
|
||||||
|
return ba.toULongLong(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// GdbResponse
|
// GdbResponse
|
||||||
|
@@ -127,6 +127,7 @@ public:
|
|||||||
GdbMi findChild(const char *name) const;
|
GdbMi findChild(const char *name) const;
|
||||||
|
|
||||||
QByteArray toString(bool multiline = false, int indent = 0) const;
|
QByteArray toString(bool multiline = false, int indent = 0) const;
|
||||||
|
qulonglong toAddress() const;
|
||||||
void fromString(const QByteArray &str);
|
void fromString(const QByteArray &str);
|
||||||
void fromStringMultiple(const QByteArray &str);
|
void fromStringMultiple(const QByteArray &str);
|
||||||
void setStreamOutput(const QByteArray &name, const QByteArray &content);
|
void setStreamOutput(const QByteArray &name, const QByteArray &content);
|
||||||
|
@@ -752,9 +752,8 @@ void setWatchDataAddress(WatchData &data, const GdbMi &addressMi, const GdbMi &o
|
|||||||
data.dumperFlags = addressBA;
|
data.dumperFlags = addressBA;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const quint64 address = addressBA.toULongLong(0, 16);
|
const quint64 address = addressMi.toAddress();
|
||||||
const quint64 origAddress = origAddressMi.isValid() ?
|
const quint64 origAddress = origAddressMi.toAddress();
|
||||||
origAddressMi.data().toULongLong(0, 16) : quint64(0);
|
|
||||||
setWatchDataAddress(data, address, origAddress);
|
setWatchDataAddress(data, address, origAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2564,6 +2564,9 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
int *x = new int(32);
|
int *x = new int(32);
|
||||||
Q_UNUSED(x);
|
Q_UNUSED(x);
|
||||||
|
std::string s;
|
||||||
|
s = "hallo";
|
||||||
|
s += "hallo";
|
||||||
testQXmlAttributes();
|
testQXmlAttributes();
|
||||||
testQRegExp();
|
testQRegExp();
|
||||||
testInlineBreakpoints();
|
testInlineBreakpoints();
|
||||||
|
Reference in New Issue
Block a user