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.
|
||||
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.
|
||||
# FIXME: This is not available on 'bbsetup' time, only at 'bb' time.
|
||||
|
||||
@@ -1049,9 +1052,18 @@ def bbsetup():
|
||||
except:
|
||||
pass
|
||||
qqFormats[name] = formats
|
||||
elif key.startswith("qedit__"):
|
||||
name = key[7:]
|
||||
try:
|
||||
qqEditable[name] = value
|
||||
except:
|
||||
pass
|
||||
result = "dumpers=["
|
||||
#qqNs = qtNamespace() # This is too early
|
||||
for key, value in qqFormats.items():
|
||||
if qqEditable.has_key(key):
|
||||
result += '{type="%s",formats="%s",editable="true"},' % (key, value)
|
||||
else:
|
||||
result += '{type="%s",formats="%s"},' % (key, value)
|
||||
result += ']'
|
||||
#result += ',namespace="%s"' % qqNs
|
||||
@@ -1059,6 +1071,36 @@ def bbsetup():
|
||||
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
|
||||
|
@@ -1354,6 +1354,18 @@ def qdump__QStandardItem(d, 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():
|
||||
return "Inline,Separate Window"
|
||||
|
||||
@@ -1925,6 +1937,13 @@ def qdump__std__vector(d, item):
|
||||
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):
|
||||
qdump__std__string(d, item)
|
||||
|
||||
|
@@ -2199,11 +2199,9 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp
|
||||
// is called <MULTIPLE>.
|
||||
//qDebug() << "ADDR: " << child.data() << (child.data() == "<MULTIPLE>");
|
||||
if (child.data().startsWith("0x")) {
|
||||
response.address = child.data().mid(2).toULongLong(0, 16);
|
||||
response.address = child.toAddress();
|
||||
} else {
|
||||
response.extra = child.data();
|
||||
if (child.data() == "<MULTIPLE>")
|
||||
response.multiple = true;
|
||||
}
|
||||
} else if (child.hasName("file")) {
|
||||
file = child.data();
|
||||
@@ -2320,7 +2318,7 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
|
||||
// Mac yields:
|
||||
//>32^done,wpt={number="4",exp="*4355182176"}
|
||||
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);
|
||||
QTC_ASSERT(!handler->needsChange(id), /**/);
|
||||
handler->notifyBreakpointInsertOk(id);
|
||||
@@ -3147,7 +3145,7 @@ StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level)
|
||||
frame.function = _(frameMi.findChild("func").data());
|
||||
frame.from = _(frameMi.findChild("from").data());
|
||||
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();
|
||||
return frame;
|
||||
}
|
||||
@@ -3902,13 +3900,22 @@ void GdbEngine::insertData(const WatchData &data0)
|
||||
watchHandler()->insertData(data);
|
||||
}
|
||||
|
||||
void GdbEngine::assignValueInDebugger(const WatchData *,
|
||||
void GdbEngine::assignValueInDebugger(const WatchData *data,
|
||||
const QString &expression, const QVariant &value)
|
||||
{
|
||||
if (hasPython()) {
|
||||
QByteArray cmd = "bbedit "
|
||||
+ data->type.toBase64() + ' '
|
||||
+ 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()),
|
||||
postCommand("-var-assign assign " +
|
||||
GdbMi::escapeCString(value.toString().toLatin1()),
|
||||
Discardable, CB(handleVarAssign));
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::watchPoint(const QPoint &pnt)
|
||||
|
@@ -373,6 +373,16 @@ GdbMi GdbMi::findChild(const char *name) const
|
||||
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
|
||||
|
@@ -127,6 +127,7 @@ public:
|
||||
GdbMi findChild(const char *name) const;
|
||||
|
||||
QByteArray toString(bool multiline = false, int indent = 0) const;
|
||||
qulonglong toAddress() const;
|
||||
void fromString(const QByteArray &str);
|
||||
void fromStringMultiple(const QByteArray &str);
|
||||
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;
|
||||
return;
|
||||
}
|
||||
const quint64 address = addressBA.toULongLong(0, 16);
|
||||
const quint64 origAddress = origAddressMi.isValid() ?
|
||||
origAddressMi.data().toULongLong(0, 16) : quint64(0);
|
||||
const quint64 address = addressMi.toAddress();
|
||||
const quint64 origAddress = origAddressMi.toAddress();
|
||||
setWatchDataAddress(data, address, origAddress);
|
||||
}
|
||||
|
||||
|
@@ -2564,6 +2564,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int *x = new int(32);
|
||||
Q_UNUSED(x);
|
||||
std::string s;
|
||||
s = "hallo";
|
||||
s += "hallo";
|
||||
testQXmlAttributes();
|
||||
testQRegExp();
|
||||
testInlineBreakpoints();
|
||||
|
Reference in New Issue
Block a user