diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index e5c5a6a4a85a166fe8528a8284be6438ca03bc99..e4e534d6a385b97a59384df31fc755025ba64075 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -439,6 +439,32 @@ def findFirstZero(p, max): p = p + 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): t = gdb.lookup_type("unsigned char").pointer() p = p.cast(t) @@ -803,6 +829,8 @@ SalCommand() # ####################################################################### +StopDisplay, DisplayImage1, DisplayString, DisplayImage, DisplayProcess = range(5) + class Dumper: def __init__(self): self.output = "" @@ -907,6 +935,14 @@ class Dumper: str = encodeString(value) 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): str = encodeByteArray(value) self.put('valueencoded="%d",value="%s",' % (6, str)) diff --git a/share/qtcreator/gdbmacros/gdbmacros.py b/share/qtcreator/gdbmacros/gdbmacros.py index 7255fed290ec09b57b913aee8c58e46602732520..b7769c3c9302d26c19cf4a43ad7c07a137d7655d 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.py +++ b/share/qtcreator/gdbmacros/gdbmacros.py @@ -406,7 +406,7 @@ def qdump__QImage(d, item): d.endChildren() format = d.itemFormat(item) if format == 0: - d.putField("editformat", 0) # Magic marker for "delete widget" + d.putDisplay(StopDisplay) elif format == 1: if False: # 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()) gdb.execute("dump binary memory %s %s %s" % (filename, cleanAddress(p), cleanAddress(p + nbytes))) - d.putField("editformat", 3) # Magic marker for external "QImage" data. - d.beginItem("editvalue") - d.put(" %d %d %d %s" % (d_ptr["width"], d_ptr["height"], - d_ptr["format"], filename)) - d.endItem() + d.putDisplay(DisplayImage, " %d %d %d %s" + % (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename)) def qdump__QLinkedList(d, item): @@ -1979,3 +1976,26 @@ def qdump__TLitC(d, item): d.putNumChild(0) 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") + diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index b8c0f1e64fc38bd7cf8e4c1b8371efd670396d2f..d046c9fcedfb57aca4e4b255ab8ff1ad4fa6770a 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -42,6 +42,7 @@ #include <QtCore/QDebug> #include <QtCore/QEvent> #include <QtCore/QFile> +#include <QtCore/QProcess> #include <QtCore/QTextStream> #include <QtCore/QTimer> #include <QtCore/QtAlgorithms> @@ -1209,12 +1210,12 @@ void WatchHandler::cleanup() m_watchers->m_fetchTriggered.clear(); m_tooltips->m_fetchTriggered.clear(); #if 1 - for (EditWindows::ConstIterator it = m_editWindows.begin(); - it != m_editWindows.end(); ++it) { + for (EditHandlers::ConstIterator it = m_editHandlers.begin(); + it != m_editHandlers.end(); ++it) { if (!it.value().isNull()) delete it.value(); } - m_editWindows.clear(); + m_editHandlers.clear(); #endif } @@ -1348,21 +1349,21 @@ static void swapEndian(char *d, int nchar) void WatchHandler::showEditValue(const WatchData &data) { - QWidget *w = m_editWindows.value(data.iname); + QObject *w = m_editHandlers.value(data.iname); if (data.editformat == 0x0) { - m_editWindows.remove(data.iname); + m_editHandlers.remove(data.iname); delete w; - } else if (data.editformat == 0x1 || data.editformat == 0x3) { + } else if (data.editformat == 1 || data.editformat == 3) { // QImage if (!w) { w = new QLabel; - m_editWindows[data.iname] = w; + m_editHandlers[data.iname] = w; } if (QLabel *l = qobject_cast<QLabel *>(w)) { int width, height, format; QByteArray ba; uchar *bits; - if (data.editformat == 0x1) { + if (data.editformat == 1) { ba = QByteArray::fromHex(data.editvalue); const int *header = (int *)(ba.data()); swapEndian(ba.data(), ba.size()); @@ -1370,7 +1371,7 @@ void WatchHandler::showEditValue(const WatchData &data) width = header[0]; height = header[1]; format = header[2]; - } else { // data.editformat == 0x3 + } else { // data.editformat == 3 QTextStream ts(data.editvalue); QString fileName; ts >> width >> height >> format >> fileName; @@ -1384,11 +1385,11 @@ void WatchHandler::showEditValue(const WatchData &data) l->resize(width, height); l->show(); } - } else if (data.editformat == 0x2) { + } else if (data.editformat == 2) { // QString if (!w) { w = new QTextEdit; - m_editWindows[data.iname] = w; + m_editHandlers[data.iname] = w; } QByteArray ba = QByteArray::fromHex(data.editvalue); 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->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 { QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat); } diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index e2f4ddf0f930c73e14d1aa9d5c429f3c7efdd5fb..d6b26ef6bdf83cb9c0ad010609936d8c9343e2a1 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -282,14 +282,17 @@ private: bool m_expandPointers; bool m_inChange; - typedef QMap<QString, QPointer<QWidget> > EditWindows; - EditWindows m_editWindows; + // QWidgets and QProcesses taking care of special displays. + typedef QMap<QString, QPointer<QObject> > EditHandlers; + EditHandlers m_editHandlers; QHash<QByteArray, int> m_watcherNames; QByteArray watcherName(const QByteArray &exp); QHash<QString, int> m_typeFormats; 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_watchers; diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp index 18540d2cfb37eb9385ac7a3c8f15bceebfb7e5e4..36b3940701efc55f617b85d241e42236c995120a 100644 --- a/tests/manual/gdbdebugger/simple/app.cpp +++ b/tests/manual/gdbdebugger/simple/app.cpp @@ -361,6 +361,28 @@ void testQImage() 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() { qDebug() << "qDebug() 1"; @@ -1467,6 +1489,7 @@ int main(int argc, char *argv[]) list2 << 0; testQStandardItemModel(); + testFunction(); testQImage(); testNoArgumentName(1, 2, 3); testIO();