Commit 62fb2227 authored by Thiago Macieira's avatar Thiago Macieira

Debugger: Add dumper support for IPv6 in QHostAddress

Change-Id: Ia542cf9e3c695a2c3c4b6340c3d72dfe743339c6
Reviewed-by: default avatarThiago Macieira <thiago.macieira@intel.com>
parent f6a9a69e
......@@ -545,8 +545,9 @@ Hex2EncodedUInt2, \
Hex2EncodedUInt4, \
Hex2EncodedUInt8, \
Hex2EncodedFloat4, \
Hex2EncodedFloat8 \
= range(27)
Hex2EncodedFloat8, \
IPv6AddressAndHexScopeId \
= range(28)
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
StopDisplay, \
......@@ -1577,6 +1578,9 @@ class Dumper:
def extractInt(self, addr):
return long(gdb.Value(addr).cast(self.intPtrType()).dereference())
def extractByte(self, addr):
return long(gdb.Value(addr).cast(self.charPtrType()).dereference()) & 0xFF
# Do not use value.address here as this might not have one,
# i.e. be the result of an inferior call
def dereferenceValue(self, value):
......
......@@ -60,8 +60,9 @@ Hex2EncodedUInt2, \
Hex2EncodedUInt4, \
Hex2EncodedUInt8, \
Hex2EncodedFloat4, \
Hex2EncodedFloat8 \
= range(27)
Hex2EncodedFloat8, \
IPv6AddressAndHexScopeId \
= range(28)
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
StopDisplay, \
......@@ -643,6 +644,9 @@ class Dumper:
def extractInt(self, address):
return int(self.createValue(address, self.intType()))
def extractByte(self, address):
return int(self.createValue(address, self.charType())) & 0xFF
def handleCommand(self, command):
result = lldb.SBCommandReturnObject()
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
......
......@@ -723,21 +723,55 @@ def qdump__QHash__iterator(d, value):
def qdump__QHostAddress(d, value):
# QHostAddress in Qt 4.5 (byte offsets)
# quint32 a (0)
# Q_IPV6ADDR a6 (4)
# protocol (20)
# QString ipString (24)
# QString scopeId (24 + ptrSize)
# bool isParsed (24 + 2 * ptrSize)
# QHostAddress in Qt 5.0
# QString ipString (0)
# QString scopeId (ptrSize)
# quint32 a (2*ptrSize)
# Q_IPV6ADDR a6 (2*ptrSize + 4)
# protocol (2*ptrSize + 20)
# bool isParsed (2*ptrSize + 24)
privAddress = d.dereferenceValue(value)
isQt5 = d.qtVersion() >= 0x050000
sizeofQString = d.ptrSize()
ipStringAddress = privAddress + (0 if isQt5 else 24)
isParsedAddress = privAddress + 24 + 2 * sizeofQString
# value.d.d->ipString
ipString = qEncodeString(d, d.dereference(ipStringAddress))
if len(ipString) > 0:
if d.extractByte(isParsedAddress) and len(ipString) > 0:
d.putValue(ipString, Hex4EncodedLittleEndian)
else:
# value.d.d->a
a = d.extractInt(privAddress + (2 * d.ptrSize() if isQt5 else 0))
a, n4 = divmod(a, 256)
a, n3 = divmod(a, 256)
a, n2 = divmod(a, 256)
a, n1 = divmod(a, 256)
d.putValue("%d.%d.%d.%d" % (n1, n2, n3, n4))
# value.d.d->protocol:
# QAbstractSocket::IPv4Protocol = 0
# QAbstractSocket::IPv6Protocol = 1
protoAddress = privAddress + 20 + (2 * sizeofQString if isQt5 else 0);
proto = d.extractInt(protoAddress)
if proto == 1:
# value.d.d->a6
a6 = privAddress + 4 + (2 * sizeofQString if isQt5 else 0)
data = d.readRawMemory(a6, 16)
address = ':'.join("%x" % int(data[i:i+4], 16) for i in xrange(0, 32, 4))
scopeId = privAddress + sizeofQString + (0 if isQt5 else 24)
scopeId = qEncodeString(d, d.dereference(scopeId))
d.putValue("%s%%%s" % (address, scopeId), IPv6AddressAndHexScopeId)
elif proto == 0:
# value.d.d->a
a = d.extractInt(privAddress + (2 * sizeofQString if isQt5 else 0))
a, n4 = divmod(a, 256)
a, n3 = divmod(a, 256)
a, n2 = divmod(a, 256)
a, n1 = divmod(a, 256)
d.putValue("%d.%d.%d.%d" % (n1, n2, n3, n4));
else:
d.putValue("<unspecified>")
d.putPlainChildren(value["d"]["d"].dereference())
......
......@@ -32,6 +32,7 @@
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QHostAddress>
#include <ctype.h>
......@@ -611,6 +612,18 @@ QString decodeData(const QByteArray &ba, int encoding)
const QTime time = timeFromData(ba.mid(p + 1 ).toInt());
return QDateTime(date, time).toString(Qt::TextDate);
}
case IPv6AddressAndHexScopeId: { // 27, 16 hex-encoded bytes, "%" and the string-encoded scope
const int p = ba.indexOf('%');
QHostAddress ip6(QString::fromLatin1(p == -1 ? ba : ba.left(p)));
if (ip6.isNull())
break;
const QByteArray scopeId = p == -1 ? QByteArray() : QByteArray::fromHex(ba.mid(p + 1));
if (!scopeId.isEmpty())
ip6.setScopeId(QString::fromUtf16(reinterpret_cast<const ushort *>(scopeId.constData()),
scopeId.length() / 2));
return ip6.toString();
}
}
qDebug() << "ENCODING ERROR: " << encoding;
return QCoreApplication::translate("Debugger", "<Encoding error>");
......
......@@ -202,7 +202,8 @@ enum DebuggerEncoding
Hex2EncodedUInt4 = 23,
Hex2EncodedUInt8 = 24,
Hex2EncodedFloat4 = 25,
Hex2EncodedFloat8 = 26
Hex2EncodedFloat8 = 26,
IPv6AddressAndHexScopeId = 27
};
// Keep in sync with dumper.py, symbolgroupvalue.cpp of CDB
......
......@@ -1020,11 +1020,12 @@ namespace qhostaddress {
{
QHostAddress ha1(129u * 256u * 256u * 256u + 130u);
QHostAddress ha2("127.0.0.1");
uint ip2 = ha2.toIPv4Address();
BREAK_HERE;
// Check ha1 129.0.0.130 QHostAddress.
// Check ha2 "127.0.0.1" QHostAddress.
// Continue.
dummyStatement(&ha1, &ha2);
dummyStatement(&ha1, &ha2, &ip2);
}
void testQHostAddress2()
......@@ -1041,6 +1042,7 @@ namespace qhostaddress {
addr.c[14] = 0;
addr.c[15] = 0;
QHostAddress ha1(addr);
ha1.setScopeId(QLatin1String("wlan0"));
BREAK_HERE;
// Continue.
dummyStatement(&ha1);
......
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