From 6965fc30b18bfd77b15f633807f8abeba46d75ba Mon Sep 17 00:00:00 2001 From: hjk <hjk@theqtcompany.com> Date: Wed, 15 Apr 2015 12:38:11 +0200 Subject: [PATCH] Debugger: Disable parts of QDate* dumper for GDB on 32 bit Older versions of GDB (~GDB 7.4 on 32 bit) will cause segmentation faults in inferior calls due to misaligned %ebx values in an SSE call in qstring.cpp:findChar. Change-Id: I44492106080f12e645f9d57828438ec70fd66ca6 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com> --- share/qtcreator/debugger/dumper.py | 5 +++ share/qtcreator/debugger/gdbbridge.py | 28 +++++++-------- share/qtcreator/debugger/qttypes.py | 51 ++++++++++++++------------- tests/auto/debugger/tst_dumpers.cpp | 48 +++++++++++++++---------- 4 files changed, 73 insertions(+), 59 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 0bf0bd28353..6a3e2b5afcf 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -1792,6 +1792,11 @@ class DumperBase: return True return functionName.startswith(self.qtNamespace() + "QV4::") + # Hack to avoid QDate* dumper timeouts with GDB 7.4 on 32 bit + # due to misaligned %ebx in SSE calls (qstring.cpp:findChar) + def canCallLocale(self): + return True + def isReportableQmlFrame(self, functionName): return functionName and functionName.find("QV4::Moth::VME::exec") >= 0 diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 890a39c158e..2c840cce039 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -346,6 +346,11 @@ class Dumper(DumperBase): return items + # Hack to avoid QDate* dumper timeouts with GDB 7.4 on 32 bit + # due to misaligned %ebx in SSE calls (qstring.cpp:findChar) + # This seems to be fixed in 7.9 (or earlier) + def canCallLocale(self): + return False if self.is32bit() else True def showData(self, args): self.prepare(args) @@ -1653,8 +1658,8 @@ class CliDumper(Dumper): self.indent = 0 self.isCli = True - def reportDumpers(self): - return "" + def reportDumpers(self, msg): + return msg def enterSubItem(self, item): if not item.iname: @@ -1734,20 +1739,11 @@ class CliDumper(Dumper): return True def showData(self, args): - arglist = args.split(' ') - name = '' - if len(arglist) >= 1: - name = arglist[0] - allexpanded = [name] - if len(arglist) >= 2: - for sub in arglist[1].split(','): - allexpanded.append(name + '.' + sub) - pars = {} - pars['fancy': 1] - pars['passException': 1] - pars['autoderef': 1] - pars['expanded': allexpanded] - self.prepare(pars) + args['fancy'] = 1 + args['passException'] = 1 + args['autoderef'] = 1 + name = args['varlist'] + self.prepare(args) self.output = name + ' = ' frame = gdb.selected_frame() value = frame.read_var(name) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 031c72bf48f..9078b3b7542 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -198,14 +198,15 @@ def qdump__QDate(d, value): if d.isExpanded(): # FIXME: This improperly uses complex return values. with Children(d): - d.putCallItem("toString", value, "toString", - d.enumExpression("DateFormat", "TextDate")) - d.putCallItem("(ISO)", value, "toString", - d.enumExpression("DateFormat", "ISODate")) - d.putCallItem("(SystemLocale)", value, "toString", - d.enumExpression("DateFormat", "SystemLocaleDate")) - d.putCallItem("(Locale)", value, "toString", - d.enumExpression("DateFormat", "LocaleDate")) + if d.canCallLocale(): + d.putCallItem("toString", value, "toString", + d.enumExpression("DateFormat", "TextDate")) + d.putCallItem("(ISO)", value, "toString", + d.enumExpression("DateFormat", "ISODate")) + d.putCallItem("(SystemLocale)", value, "toString", + d.enumExpression("DateFormat", "SystemLocaleDate")) + d.putCallItem("(Locale)", value, "toString", + d.enumExpression("DateFormat", "LocaleDate")) d.putFields(value) else: d.putValue("(invalid)") @@ -224,10 +225,11 @@ def qdump__QTime(d, value): d.enumExpression("DateFormat", "TextDate")) d.putCallItem("(ISO)", value, "toString", d.enumExpression("DateFormat", "ISODate")) - d.putCallItem("(SystemLocale)", value, "toString", - d.enumExpression("DateFormat", "SystemLocaleDate")) - d.putCallItem("(Locale)", value, "toString", - d.enumExpression("DateFormat", "LocaleDate")) + if d.canCallLocale(): + d.putCallItem("(SystemLocale)", value, "toString", + d.enumExpression("DateFormat", "SystemLocaleDate")) + d.putCallItem("(Locale)", value, "toString", + d.enumExpression("DateFormat", "LocaleDate")) d.putFields(value) else: d.putValue("(invalid)") @@ -305,18 +307,19 @@ def qdump__QDateTime(d, value): # FIXME: This improperly uses complex return values. with Children(d): d.putCallItem("toTime_t", value, "toTime_t") - d.putCallItem("toString", value, "toString", - d.enumExpression("DateFormat", "TextDate")) - d.putCallItem("(ISO)", value, "toString", - d.enumExpression("DateFormat", "ISODate")) - d.putCallItem("(SystemLocale)", value, "toString", - d.enumExpression("DateFormat", "SystemLocaleDate")) - d.putCallItem("(Locale)", value, "toString", - d.enumExpression("DateFormat", "LocaleDate")) - d.putCallItem("toUTC", value, "toTimeSpec", - d.enumExpression("TimeSpec", "UTC")) - d.putCallItem("toLocalTime", value, "toTimeSpec", - d.enumExpression("TimeSpec", "LocalTime")) + if d.canCallLocale(): + d.putCallItem("toString", value, "toString", + d.enumExpression("DateFormat", "TextDate")) + d.putCallItem("(ISO)", value, "toString", + d.enumExpression("DateFormat", "ISODate")) + d.putCallItem("toUTC", value, "toTimeSpec", + d.enumExpression("TimeSpec", "UTC")) + d.putCallItem("(SystemLocale)", value, "toString", + d.enumExpression("DateFormat", "SystemLocaleDate")) + d.putCallItem("(Locale)", value, "toString", + d.enumExpression("DateFormat", "LocaleDate")) + d.putCallItem("toLocalTime", value, "toTimeSpec", + d.enumExpression("TimeSpec", "LocalTime")) d.putFields(value) else: d.putValue("(invalid)") diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index d775086051d..d2a87df83b3 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -383,6 +383,8 @@ struct UnsubstitutedValue : Value UnsubstitutedValue(const QByteArray &value) : Value(value) { substituteNamespace = false; } }; +struct Optional {}; + struct Type { Type() : qtVersion(0), isPattern(false) {} @@ -454,12 +456,13 @@ enum DebuggerEngine struct CheckBase { - CheckBase() : enginesForCheck(AllEngines) {} + CheckBase() : enginesForCheck(AllEngines), optionallyPresent(false) {} mutable int enginesForCheck; mutable VersionBase debuggerVersionForCheck; mutable VersionBase gccVersionForCheck; mutable VersionBase clangVersionForCheck; mutable QtVersion qtVersionForCheck; + mutable bool optionallyPresent; }; struct Check : CheckBase @@ -486,6 +489,12 @@ struct Check : CheckBase && qtVersionForCheck.covers(context.qtVersion); } + const Check &operator%(Optional) const + { + optionallyPresent = true; + return *this; + } + const Check &operator%(DebuggerEngine engine) { enginesForCheck = engine; @@ -1429,16 +1438,17 @@ void tst_Dumpers::dumper() } if (!data.checks.isEmpty()) { - bool fail = false; qDebug() << "SOME TESTS NOT EXECUTED: "; foreach (const Check &check, data.checks) { - qDebug() << " TEST NOT FOUND FOR INAME: " << check.iname; - if (!fail && check.expectedValue.qtVersion != 0) - fail = true; + if (check.optionallyPresent) { + qDebug() << " OPTIONAL TEST NOT FOUND FOR INAME: " << check.iname << " IGNORED."; + } else { + qDebug() << " COMPULSORY TEST NOT FOUND FOR INAME: " << check.iname; + ok = false; + } } qDebug() << "SEEN INAMES " << seenINames; qDebug() << "EXPANDED : " << expanded; - ok = false; } if (ok) { m_keepTemp = false; @@ -1592,33 +1602,33 @@ void tst_Dumpers::dumper_data() + Check("d0", "(invalid)", "@QDate") + Check("d1", "Tue Jan 1 1980", "@QDate") - + Check("d1.(ISO)", "\"1980-01-01\"", "@QString") % NoCdbEngine - + CheckType("d1.(Locale)", "@QString") % NoCdbEngine - + CheckType("d1.(SystemLocale)", "@QString") % NoCdbEngine - + Check("d1.toString", "\"Tue Jan 1 1980\"", "@QString") % NoCdbEngine + + Check("d1.(ISO)", "\"1980-01-01\"", "@QString") % NoCdbEngine % Optional() + + Check("d1.toString", "\"Tue Jan 1 1980\"", "@QString") % NoCdbEngine % Optional() + + CheckType("d1.(Locale)", "@QString") % NoCdbEngine % Optional() + + CheckType("d1.(SystemLocale)", "@QString") % NoCdbEngine % Optional() + Check("t0", "(invalid)", "@QTime") + Check("t1", "13:15:32", "@QTime") + Check("t1.(ISO)", "\"13:15:32\"", "@QString") % NoCdbEngine - + CheckType("t1.(Locale)", "@QString") % NoCdbEngine - + CheckType("t1.(SystemLocale)", "@QString") % NoCdbEngine + Check("t1.toString", "\"13:15:32\"", "@QString") % NoCdbEngine + + CheckType("t1.(Locale)", "@QString") % NoCdbEngine % Optional() + + CheckType("t1.(SystemLocale)", "@QString") % NoCdbEngine % Optional() + Check("dt0", "(invalid)", "@QDateTime") + Check("dt1", Value4("Tue Jan 1 13:15:32 1980"), "@QDateTime") + Check("dt1", Value5("Tue Jan 1 13:15:32 1980 GMT"), "@QDateTime") + Check("dt1.(ISO)", - "\"1980-01-01T13:15:32Z\"", "@QString") % NoCdbEngine - + CheckType("dt1.(Locale)", "@QString") % NoCdbEngine - + CheckType("dt1.(SystemLocale)", "@QString") % NoCdbEngine + "\"1980-01-01T13:15:32Z\"", "@QString") % NoCdbEngine % Optional() + + CheckType("dt1.(Locale)", "@QString") % NoCdbEngine % Optional() + + CheckType("dt1.(SystemLocale)", "@QString") % NoCdbEngine % Optional() + Check("dt1.toString", - Value4("\"Tue Jan 1 13:15:32 1980\""), "@QString") % NoCdbEngine + Value4("\"Tue Jan 1 13:15:32 1980\""), "@QString") % NoCdbEngine % Optional() + Check("dt1.toString", - Value5("\"Tue Jan 1 13:15:32 1980 GMT\""), "@QString") % NoCdbEngine + Value5("\"Tue Jan 1 13:15:32 1980 GMT\""), "@QString") % NoCdbEngine % Optional() + Check("dt1.toUTC", - Value4("Tue Jan 1 13:15:32 1980"), "@QDateTime") % NoCdbEngine + Value4("Tue Jan 1 13:15:32 1980"), "@QDateTime") % NoCdbEngine % Optional() + Check("dt1.toUTC", - Value5("Tue Jan 1 13:15:32 1980 GMT"), "@QDateTime") % NoCdbEngine; + Value5("Tue Jan 1 13:15:32 1980 GMT"), "@QDateTime") % NoCdbEngine % Optional(); #ifdef Q_OS_WIN QByteArray tempDir = "\"C:/Program Files\""; -- GitLab