forked from qt-creator/qt-creator
debugger: code cosmetics for custom displays
This commit is contained in:
@@ -439,6 +439,32 @@ def findFirstZero(p, max):
|
|||||||
p = p + 1
|
p = p + 1
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
def extractCharArray(p, maxsize):
|
||||||
|
t = gdb.lookup_type("unsigned char").pointer()
|
||||||
|
p = p.cast(t)
|
||||||
|
i = findFirstZero(p, maxsize)
|
||||||
|
limit = select(i < 0, maxsize, i)
|
||||||
|
s = ""
|
||||||
|
for i in xrange(limit):
|
||||||
|
s += "%c" % int(p.dereference())
|
||||||
|
p += 1
|
||||||
|
if i == maxsize:
|
||||||
|
s += "..."
|
||||||
|
return s
|
||||||
|
|
||||||
|
def extractByteArray(value):
|
||||||
|
d_ptr = value['d'].dereference()
|
||||||
|
data = d_ptr['data']
|
||||||
|
size = d_ptr['size']
|
||||||
|
alloc = d_ptr['alloc']
|
||||||
|
check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||||
|
checkRef(d_ptr["ref"])
|
||||||
|
if size > 0:
|
||||||
|
checkAccess(data, 4)
|
||||||
|
checkAccess(data + size) == 0
|
||||||
|
return extractCharArray(data, 100)
|
||||||
|
|
||||||
def encodeCharArray(p, maxsize, size = -1):
|
def encodeCharArray(p, maxsize, size = -1):
|
||||||
t = gdb.lookup_type("unsigned char").pointer()
|
t = gdb.lookup_type("unsigned char").pointer()
|
||||||
p = p.cast(t)
|
p = p.cast(t)
|
||||||
@@ -803,6 +829,8 @@ SalCommand()
|
|||||||
#
|
#
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
StopDisplay, DisplayImage1, DisplayString, DisplayImage, DisplayProcess = range(5)
|
||||||
|
|
||||||
class Dumper:
|
class Dumper:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.output = ""
|
self.output = ""
|
||||||
@@ -907,6 +935,14 @@ class Dumper:
|
|||||||
str = encodeString(value)
|
str = encodeString(value)
|
||||||
self.put('valueencoded="%d",value="%s",' % (7, str))
|
self.put('valueencoded="%d",value="%s",' % (7, str))
|
||||||
|
|
||||||
|
def putDisplay(self, format, value = None, cmd = None):
|
||||||
|
self.put('editformat="%s",' % format)
|
||||||
|
if cmd is None:
|
||||||
|
if not value is None:
|
||||||
|
self.put('editvalue="%s",' % value)
|
||||||
|
else:
|
||||||
|
self.put('editvalue="%s|%s",' % (cmd, value))
|
||||||
|
|
||||||
def putByteArrayValue(self, value):
|
def putByteArrayValue(self, value):
|
||||||
str = encodeByteArray(value)
|
str = encodeByteArray(value)
|
||||||
self.put('valueencoded="%d",value="%s",' % (6, str))
|
self.put('valueencoded="%d",value="%s",' % (6, str))
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ def qdump__QImage(d, item):
|
|||||||
d.endChildren()
|
d.endChildren()
|
||||||
format = d.itemFormat(item)
|
format = d.itemFormat(item)
|
||||||
if format == 0:
|
if format == 0:
|
||||||
d.putField("editformat", 0) # Magic marker for "delete widget"
|
d.putDisplay(StopDisplay)
|
||||||
elif format == 1:
|
elif format == 1:
|
||||||
if False:
|
if False:
|
||||||
# Take four bytes at a time, this is critical for performance.
|
# Take four bytes at a time, this is critical for performance.
|
||||||
@@ -428,11 +428,8 @@ def qdump__QImage(d, item):
|
|||||||
p = bits.cast(gdb.lookup_type("unsigned char").pointer())
|
p = bits.cast(gdb.lookup_type("unsigned char").pointer())
|
||||||
gdb.execute("dump binary memory %s %s %s" %
|
gdb.execute("dump binary memory %s %s %s" %
|
||||||
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
|
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
|
||||||
d.putField("editformat", 3) # Magic marker for external "QImage" data.
|
d.putDisplay(DisplayImage, " %d %d %d %s"
|
||||||
d.beginItem("editvalue")
|
% (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename))
|
||||||
d.put(" %d %d %d %s" % (d_ptr["width"], d_ptr["height"],
|
|
||||||
d_ptr["format"], filename))
|
|
||||||
d.endItem()
|
|
||||||
|
|
||||||
|
|
||||||
def qdump__QLinkedList(d, item):
|
def qdump__QLinkedList(d, item):
|
||||||
@@ -1979,3 +1976,26 @@ def qdump__TLitC(d, item):
|
|||||||
d.putNumChild(0)
|
d.putNumChild(0)
|
||||||
d.putValue(encodeSymbianString(base, size), "7")
|
d.putValue(encodeSymbianString(base, size), "7")
|
||||||
|
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
#
|
||||||
|
# Display Test
|
||||||
|
#
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
if False:
|
||||||
|
def qdump__Function(d, item):
|
||||||
|
min = item.value["min"]
|
||||||
|
max = item.value["max"]
|
||||||
|
var = extractByteArray(item.value["var"])
|
||||||
|
f = extractByteArray(item.value["f"])
|
||||||
|
d.putValue("%s, %s=%f..%f" % (f, var, min, max))
|
||||||
|
d.putNumChild(0)
|
||||||
|
d.putField("typeformats", "Normal,Displayed");
|
||||||
|
format = d.itemFormat(item)
|
||||||
|
if format == 0:
|
||||||
|
d.putDisplay(StopDisplay)
|
||||||
|
elif format == 1:
|
||||||
|
input = "plot [%s=%f:%f] %s" % (var, min, max, f)
|
||||||
|
d.putDisplay(DisplayProcess, input, "gnuplot")
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QEvent>
|
#include <QtCore/QEvent>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QProcess>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtCore/QtAlgorithms>
|
#include <QtCore/QtAlgorithms>
|
||||||
@@ -1209,12 +1210,12 @@ void WatchHandler::cleanup()
|
|||||||
m_watchers->m_fetchTriggered.clear();
|
m_watchers->m_fetchTriggered.clear();
|
||||||
m_tooltips->m_fetchTriggered.clear();
|
m_tooltips->m_fetchTriggered.clear();
|
||||||
#if 1
|
#if 1
|
||||||
for (EditWindows::ConstIterator it = m_editWindows.begin();
|
for (EditHandlers::ConstIterator it = m_editHandlers.begin();
|
||||||
it != m_editWindows.end(); ++it) {
|
it != m_editHandlers.end(); ++it) {
|
||||||
if (!it.value().isNull())
|
if (!it.value().isNull())
|
||||||
delete it.value();
|
delete it.value();
|
||||||
}
|
}
|
||||||
m_editWindows.clear();
|
m_editHandlers.clear();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,21 +1349,21 @@ static void swapEndian(char *d, int nchar)
|
|||||||
|
|
||||||
void WatchHandler::showEditValue(const WatchData &data)
|
void WatchHandler::showEditValue(const WatchData &data)
|
||||||
{
|
{
|
||||||
QWidget *w = m_editWindows.value(data.iname);
|
QObject *w = m_editHandlers.value(data.iname);
|
||||||
if (data.editformat == 0x0) {
|
if (data.editformat == 0x0) {
|
||||||
m_editWindows.remove(data.iname);
|
m_editHandlers.remove(data.iname);
|
||||||
delete w;
|
delete w;
|
||||||
} else if (data.editformat == 0x1 || data.editformat == 0x3) {
|
} else if (data.editformat == 1 || data.editformat == 3) {
|
||||||
// QImage
|
// QImage
|
||||||
if (!w) {
|
if (!w) {
|
||||||
w = new QLabel;
|
w = new QLabel;
|
||||||
m_editWindows[data.iname] = w;
|
m_editHandlers[data.iname] = w;
|
||||||
}
|
}
|
||||||
if (QLabel *l = qobject_cast<QLabel *>(w)) {
|
if (QLabel *l = qobject_cast<QLabel *>(w)) {
|
||||||
int width, height, format;
|
int width, height, format;
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
uchar *bits;
|
uchar *bits;
|
||||||
if (data.editformat == 0x1) {
|
if (data.editformat == 1) {
|
||||||
ba = QByteArray::fromHex(data.editvalue);
|
ba = QByteArray::fromHex(data.editvalue);
|
||||||
const int *header = (int *)(ba.data());
|
const int *header = (int *)(ba.data());
|
||||||
swapEndian(ba.data(), ba.size());
|
swapEndian(ba.data(), ba.size());
|
||||||
@@ -1370,7 +1371,7 @@ void WatchHandler::showEditValue(const WatchData &data)
|
|||||||
width = header[0];
|
width = header[0];
|
||||||
height = header[1];
|
height = header[1];
|
||||||
format = header[2];
|
format = header[2];
|
||||||
} else { // data.editformat == 0x3
|
} else { // data.editformat == 3
|
||||||
QTextStream ts(data.editvalue);
|
QTextStream ts(data.editvalue);
|
||||||
QString fileName;
|
QString fileName;
|
||||||
ts >> width >> height >> format >> fileName;
|
ts >> width >> height >> format >> fileName;
|
||||||
@@ -1384,11 +1385,11 @@ void WatchHandler::showEditValue(const WatchData &data)
|
|||||||
l->resize(width, height);
|
l->resize(width, height);
|
||||||
l->show();
|
l->show();
|
||||||
}
|
}
|
||||||
} else if (data.editformat == 0x2) {
|
} else if (data.editformat == 2) {
|
||||||
// QString
|
// QString
|
||||||
if (!w) {
|
if (!w) {
|
||||||
w = new QTextEdit;
|
w = new QTextEdit;
|
||||||
m_editWindows[data.iname] = w;
|
m_editHandlers[data.iname] = w;
|
||||||
}
|
}
|
||||||
QByteArray ba = QByteArray::fromHex(data.editvalue);
|
QByteArray ba = QByteArray::fromHex(data.editvalue);
|
||||||
QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
|
QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
|
||||||
@@ -1398,6 +1399,19 @@ void WatchHandler::showEditValue(const WatchData &data)
|
|||||||
t->resize(400, 200);
|
t->resize(400, 200);
|
||||||
t->show();
|
t->show();
|
||||||
}
|
}
|
||||||
|
} else if (data.editformat == 4) {
|
||||||
|
// Generic Process.
|
||||||
|
int pos = data.editvalue.indexOf('|');
|
||||||
|
QByteArray cmd = data.editvalue.left(pos);
|
||||||
|
QByteArray input = data.editvalue.mid(pos + 1);
|
||||||
|
QProcess *p = qobject_cast<QProcess *>(w);
|
||||||
|
if (!p) {
|
||||||
|
p = new QProcess;
|
||||||
|
p->start(cmd);
|
||||||
|
p->waitForStarted();
|
||||||
|
m_editHandlers[data.iname] = p;
|
||||||
|
}
|
||||||
|
p->write(input + "\n");
|
||||||
} else {
|
} else {
|
||||||
QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat);
|
QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,14 +282,17 @@ private:
|
|||||||
bool m_expandPointers;
|
bool m_expandPointers;
|
||||||
bool m_inChange;
|
bool m_inChange;
|
||||||
|
|
||||||
typedef QMap<QString, QPointer<QWidget> > EditWindows;
|
// QWidgets and QProcesses taking care of special displays.
|
||||||
EditWindows m_editWindows;
|
typedef QMap<QString, QPointer<QObject> > EditHandlers;
|
||||||
|
EditHandlers m_editHandlers;
|
||||||
|
|
||||||
QHash<QByteArray, int> m_watcherNames;
|
QHash<QByteArray, int> m_watcherNames;
|
||||||
QByteArray watcherName(const QByteArray &exp);
|
QByteArray watcherName(const QByteArray &exp);
|
||||||
QHash<QString, int> m_typeFormats;
|
QHash<QString, int> m_typeFormats;
|
||||||
QHash<QString, int> m_individualFormats;
|
QHash<QString, int> m_individualFormats;
|
||||||
QSet<QByteArray> m_expandedINames; // Those expanded in the treeview.
|
|
||||||
|
// Items expanded in the Locals & Watchers view.
|
||||||
|
QSet<QByteArray> m_expandedINames;
|
||||||
|
|
||||||
WatchModel *m_locals;
|
WatchModel *m_locals;
|
||||||
WatchModel *m_watchers;
|
WatchModel *m_watchers;
|
||||||
|
|||||||
@@ -361,6 +361,28 @@ void testQImage()
|
|||||||
pain.end();
|
pain.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Function
|
||||||
|
{
|
||||||
|
Function(QByteArray var, QByteArray f, double min, double max)
|
||||||
|
: var(var), f(f), min(min), max(max) {}
|
||||||
|
QByteArray var;
|
||||||
|
QByteArray f;
|
||||||
|
double min;
|
||||||
|
double max;
|
||||||
|
};
|
||||||
|
|
||||||
|
void testFunction()
|
||||||
|
{
|
||||||
|
Function func("x", "sin(x)", 0, 1);
|
||||||
|
func.max = 10;
|
||||||
|
func.f = "cos(x)";
|
||||||
|
func.max = 4;
|
||||||
|
func.max = 5;
|
||||||
|
func.max = 6;
|
||||||
|
func.max = 7;
|
||||||
|
func.max = 8;
|
||||||
|
}
|
||||||
|
|
||||||
void testIO()
|
void testIO()
|
||||||
{
|
{
|
||||||
qDebug() << "qDebug() 1";
|
qDebug() << "qDebug() 1";
|
||||||
@@ -1467,6 +1489,7 @@ int main(int argc, char *argv[])
|
|||||||
list2 << 0;
|
list2 << 0;
|
||||||
|
|
||||||
testQStandardItemModel();
|
testQStandardItemModel();
|
||||||
|
testFunction();
|
||||||
testQImage();
|
testQImage();
|
||||||
testNoArgumentName(1, 2, 3);
|
testNoArgumentName(1, 2, 3);
|
||||||
testIO();
|
testIO();
|
||||||
|
|||||||
Reference in New Issue
Block a user