From 600a2f839e8e37aef410aa20df653d580943bcf9 Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Tue, 29 Nov 2011 12:20:06 +0100 Subject: [PATCH] debugger: make use of dynamic type for dumpers configurable It's too expensive to have it unconditionally on in some settings. Giving the user the possibility to switch it off seems ok. Change-Id: I7bdcb0ce919f0dca83a4563ac83958efdeb251e7 Reviewed-by: hjk <qthjk@ovi.com> --- share/qtcreator/dumper/dumper.py | 60 +++++++++++++------ src/plugins/debugger/debuggeractions.cpp | 8 +++ src/plugins/debugger/debuggeractions.h | 1 + src/plugins/debugger/gdb/gdboptionspage.cpp | 3 + src/plugins/debugger/gdb/gdboptionspage.ui | 20 +++++-- src/plugins/debugger/gdb/pythongdbengine.cpp | 6 +- src/plugins/debugger/watchwindow.cpp | 1 + .../debugger/simple/simple_test_app.cpp | 2 +- 8 files changed, 75 insertions(+), 26 deletions(-) diff --git a/share/qtcreator/dumper/dumper.py b/share/qtcreator/dumper/dumper.py index 61770db911a..32a1e5f6f5f 100644 --- a/share/qtcreator/dumper/dumper.py +++ b/share/qtcreator/dumper/dumper.py @@ -89,12 +89,39 @@ def hasInferiorThreadList(): except: return False +def dynamicTypeName(value): + #vtbl = str(parseAndEvaluate("{int(*)(int)}%s" % long(value.address))) + vtbl = gdb.execute("info symbol {int*}%s" % long(value.address), + to_string = True) + pos1 = vtbl.find("vtable ") + if pos1 != -1: + pos1 += 11 + pos2 = vtbl.find(" +", pos1) + if pos2 != -1: + return vtbl[pos1 : pos2] + return str(value.type) + def upcast(value): try: - type = value.dynamic_type - return value.cast(type) + return value.cast(value.dynamic_type) + except: + pass + #try: + # return value.cast(lookupType(dynamicTypeName(value))) + #except: + # pass + return value + +def expensiveUpcast(value): + try: + return value.cast(value.dynamic_type) except: - return value + pass + try: + return value.cast(lookupType(dynamicTypeName(value))) + except: + pass + return value typeCache = {} @@ -956,6 +983,7 @@ class Dumper: elif arg.startswith("watchers:"): watchers = base64.b16decode(arg[pos:], True) + self.useDynamicType = "dyntype" in options self.useFancy = "fancy" in options self.passExceptions = "pe" in options self.autoDerefPointers = "autoderef" in options @@ -1542,30 +1570,26 @@ class Dumper: warn("WRONG ASSUMPTION HERE: %s " % type.code) check(False) - #vtbl = str(parseAndEvaluate("{int(*)(int)}%s" % long(value.address))) - vtbl = gdb.execute("info symbol {int*}%s" % long(value.address), - to_string = True) - pos1 = vtbl.find("vtable ") - if pos1 != -1: - pos1 += 11 - pos2 = vtbl.find(" +", pos1) - if pos2 != -1: - self.putType(vtbl[pos1 : pos2], 1) + + if self.useDynamicType: + dtypeName = dynamicTypeName(value) + else: + dtypeName = typeName if self.useFancy and (format is None or format >= 1): self.putAddress(value.address) - self.putType(typeName) + self.putType(dtypeName) - if typeName in qqDumpers: - qqDumpers[typeName](self, value) + if dtypeName in qqDumpers: + qqDumpers[dtypeName](self, expensiveUpcast(value)) return - nsStrippedType = self.stripNamespaceFromType(typeName)\ + nsStrippedType = self.stripNamespaceFromType(dtypeName)\ .replace("::", "__") #warn(" STRIPPED: %s" % nsStrippedType) #warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers)) if nsStrippedType in qqDumpers: - qqDumpers[nsStrippedType](self, value) + qqDumpers[nsStrippedType](self, expensiveUpcast(value)) return # Is this derived from QObject? @@ -1580,7 +1604,7 @@ class Dumper: fields = extractFields(type) #fields = type.fields() - self.putType(typeName) + self.putType(dtypeName) self.putAddress(value.address) self.putValue("{...}") diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 86fac6ecf08..b50a72b9c9d 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -357,6 +357,14 @@ DebuggerSettings::DebuggerSettings(QSettings *settings) item->setValue(false); insertItem(AutoEnrichParameters, item); + item = new SavedAction(this); + item->setSettingsKey(debugModeGroup, QLatin1String("UseDynamicType")); + item->setText(tr("Use dynamic object type for display")); + item->setCheckable(true); + item->setDefaultValue(true); + item->setValue(true); + insertItem(UseDynamicType, item); + item = new SavedAction(this); item->setSettingsKey(debugModeGroup, QLatin1String("TargetAsync")); item->setCheckable(true); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 3f0c4bb86f8..fadfce9b245 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -120,6 +120,7 @@ enum DebuggerActionCode GdbStartupCommands, GdbWatchdogTimeout, AutoEnrichParameters, + UseDynamicType, TargetAsync, // Stack diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp index 2828ee0ec63..01a60a9a294 100644 --- a/src/plugins/debugger/gdb/gdboptionspage.cpp +++ b/src/plugins/debugger/gdb/gdboptionspage.cpp @@ -88,6 +88,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent) m_ui->checkBoxLoadGdbInit); m_group.insert(debuggerCore()->action(AutoEnrichParameters), m_ui->checkBoxAutoEnrichParameters); + m_group.insert(debuggerCore()->action(UseDynamicType), + m_ui->checkBoxUseDynamicType); m_group.insert(debuggerCore()->action(TargetAsync), m_ui->checkBoxTargetAsync); m_group.insert(debuggerCore()->action(AdjustBreakpointLocations), @@ -120,6 +122,7 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent) << sep << m_ui->groupBoxLocations->title() << sep << m_ui->checkBoxLoadGdbInit->text() << sep << m_ui->checkBoxTargetAsync->text() + << sep << m_ui->checkBoxUseDynamicType->text() << sep << m_ui->labelGdbWatchdogTimeout->text() << sep << m_ui->checkBoxEnableReverseDebugging->text() << sep << m_ui->checkBoxSkipKnownFrames->text() diff --git a/src/plugins/debugger/gdb/gdboptionspage.ui b/src/plugins/debugger/gdb/gdboptionspage.ui index a53133d4aac..a63038e07ab 100644 --- a/src/plugins/debugger/gdb/gdboptionspage.ui +++ b/src/plugins/debugger/gdb/gdboptionspage.ui @@ -92,6 +92,16 @@ on slow machines. In this case, the value should be increased.</string> </widget> </item> <item row="4" column="0" colspan="2"> + <widget class="QCheckBox" name="checkBoxUseDynamicType"> + <property name="toolTip"> + <string>This specifies whether the dynamic or the static type of objects will be displayed. Choosing the dynamic type might be slower.</string> + </property> + <property name="text"> + <string>Use dynamic object type for display</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="2"> <widget class="QCheckBox" name="checkBoxLoadGdbInit"> <property name="toolTip"> <string>This allows or inhibits reading the user's default .gdbinit file on debugger startup.</string> @@ -101,14 +111,14 @@ on slow machines. In this case, the value should be increased.</string> </property> </widget> </item> - <item row="5" column="0" colspan="2"> + <item row="6" column="0" colspan="2"> <widget class="QCheckBox" name="checkBoxTargetAsync"> <property name="text"> <string>Use asynchronous mode to control the inferior</string> </property> </widget> </item> - <item row="6" column="0" colspan="2"> + <item row="7" column="0" colspan="2"> <widget class="QCheckBox" name="checkBoxAutoEnrichParameters"> <property name="toolTip"> <string>This adds common paths to locations of debug information at debugger startup.</string> @@ -118,21 +128,21 @@ on slow machines. In this case, the value should be increased.</string> </property> </widget> </item> - <item row="7" column="0" colspan="2"> + <item row="8" column="0" colspan="2"> <widget class="QCheckBox" name="checkBoxBreakOnWarning"> <property name="text"> <string>Stop when a qWarning is issued</string> </property> </widget> </item> - <item row="8" column="0" colspan="2"> + <item row="9" column="0" colspan="2"> <widget class="QCheckBox" name="checkBoxBreakOnFatal"> <property name="text"> <string>Stop when a qFatal is issued</string> </property> </widget> </item> - <item row="9" column="0" colspan="2"> + <item row="10" column="0" colspan="2"> <widget class="QCheckBox" name="checkBoxEnableReverseDebugging"> <property name="toolTip"> <string><html><head/><body><p>Selecting this enables reverse debugging.</p><.p><b>Note:</b> This feature is very slow and unstable on the GDB side. It exhibits unpredictable behavior when going backwards over system calls and is very likely to destroy your debugging session.</p><body></html></string> diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp index 17f54be00d9..81baea0fe9c 100644 --- a/src/plugins/debugger/gdb/pythongdbengine.cpp +++ b/src/plugins/debugger/gdb/pythongdbengine.cpp @@ -93,12 +93,14 @@ void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty(); QByteArray options; + if (alwaysVerbose) + options += "pe,"; if (debuggerCore()->boolSetting(UseDebuggingHelpers)) options += "fancy,"; if (debuggerCore()->boolSetting(AutoDerefPointers)) options += "autoderef,"; - if (alwaysVerbose) - options += "pe,"; + if (debuggerCore()->boolSetting(UseDynamicType)) + options += "dyntype,"; if (options.isEmpty()) options += "defaults,"; if (params.tryPartial) diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 28bef18d5c4..7149becdbe3 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -864,6 +864,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) menu.addAction(debuggerCore()->action(ShowStdNamespace)); menu.addAction(debuggerCore()->action(ShowQtNamespace)); menu.addAction(debuggerCore()->action(SortStructMembers)); + menu.addAction(debuggerCore()->action(UseDynamicType)); QAction *actClearCodeModelSnapshot = new QAction(tr("Refresh Code Model Snapshot"), &menu); diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp index 17a528aae92..1e544180c93 100644 --- a/tests/manual/debugger/simple/simple_test_app.cpp +++ b/tests/manual/debugger/simple/simple_test_app.cpp @@ -4148,7 +4148,7 @@ namespace gdb13393 { S s(d); Base *ptr = &d; const Base *ptrConst = &d; - Base& ref = d; + Base &ref = d; const Base &refConst = d; Base **ptrToPtr = &ptr; #if USE_BOOST -- GitLab