diff options
author | hjk <[email protected]> | 2012-11-07 18:31:17 +0100 |
---|---|---|
committer | hjk <[email protected]> | 2012-11-09 11:44:22 +0100 |
commit | 6841976aa81cbbf21af7a4c15dd3823d39d5016b (patch) | |
tree | 3f9b67d846b3dc09b4ee945db4b693a246367d72 /src | |
parent | 6c6400b7b8137340a27c4fc92e3a15dfc27e1f2c (diff) |
debugger: give access to the section names in a shared object
Via context menu in the modules view, gdb-only for now.
Change-Id: I1163540cd9894c52243bb1bf0c2afc881e793863
Reviewed-by: hjk <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/debugger/debuggerconstants.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/debuggercore.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.h | 1 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.cpp | 31 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 52 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.h | 2 | ||||
-rw-r--r-- | src/plugins/debugger/moduleshandler.h | 18 | ||||
-rw-r--r-- | src/plugins/debugger/moduleswindow.cpp | 9 |
9 files changed, 119 insertions, 4 deletions
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 8d06e72ae68..eb5d41090eb 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -167,7 +167,8 @@ enum DebuggerCapabilities CatchCapability = 0x200000, //!< fork, vfork, syscall OperateByInstructionCapability = 0x400000, RunToLineCapability = 0x800000, - MemoryAddressCapability = 0x1000000 + MemoryAddressCapability = 0x1000000, + ShowModuleSectionsCapability = 0x200000 }; enum LogChannel diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h index 073435b2da1..cdc75b2c396 100644 --- a/src/plugins/debugger/debuggercore.h +++ b/src/plugins/debugger/debuggercore.h @@ -64,6 +64,7 @@ namespace Internal { class BreakHandler; class SnapshotHandler; class Symbol; +class Section; class DebuggerToolTipManager; class GlobalDebuggerOptions; @@ -113,6 +114,8 @@ public: // DebuggerEngineType et = NoEngineType) const = 0; virtual void showModuleSymbols(const QString &moduleName, const QVector<Symbol> &symbols) = 0; + virtual void showModuleSections(const QString &moduleName, + const QVector<Section> §ions) = 0; virtual void openMemoryEditor() = 0; virtual void languagesChanged() = 0; virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) = 0; diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index e467a906635..33b3c52197d 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1451,6 +1451,10 @@ void DebuggerEngine::requestModuleSymbols(const QString &) { } +void DebuggerEngine::requestModuleSections(const QString &) +{ +} + void DebuggerEngine::reloadRegisters() { } diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 8fedcf0f75b..3067bbe793e 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -179,6 +179,7 @@ public: virtual void loadSymbolsForStack(); virtual void loadAllSymbols(); virtual void requestModuleSymbols(const QString &moduleName); + virtual void requestModuleSections(const QString &moduleName); virtual void reloadRegisters(); virtual void reloadSourceFiles(); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index b1377ac4544..e2bde5e3b47 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1220,6 +1220,7 @@ public slots: QString stringSetting(int code) const; void showModuleSymbols(const QString &moduleName, const Symbols &symbols); + void showModuleSections(const QString &moduleName, const Sections §ions); bool parseArgument(QStringList::const_iterator &it, const QStringList::const_iterator &cend, QString *errorMessage); @@ -3327,6 +3328,36 @@ void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName, createNewDock(w); } +void DebuggerPluginPrivate::showModuleSections(const QString &moduleName, + const Sections §ions) +{ + QTreeWidget *w = new QTreeWidget; + w->setUniformRowHeights(true); + w->setColumnCount(5); + w->setRootIsDecorated(false); + w->setAlternatingRowColors(true); + w->setSortingEnabled(true); + w->setObjectName(QLatin1String("Sections.") + moduleName); + QStringList header; + header.append(tr("Name")); + header.append(tr("From")); + header.append(tr("To")); + header.append(tr("Address")); + header.append(tr("Flags")); + w->setHeaderLabels(header); + w->setWindowTitle(tr("Sections in \"%1\"").arg(moduleName)); + foreach (const Section &s, sections) { + QTreeWidgetItem *it = new QTreeWidgetItem; + it->setData(0, Qt::DisplayRole, s.name); + it->setData(1, Qt::DisplayRole, s.from); + it->setData(2, Qt::DisplayRole, s.to); + it->setData(3, Qt::DisplayRole, s.address); + it->setData(4, Qt::DisplayRole, s.flags); + w->addTopLevelItem(it); + } + createNewDock(w); +} + void DebuggerPluginPrivate::aboutToShutdown() { m_plugin->removeObject(this); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index fde52f9d790..d74af685a92 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -2128,6 +2128,7 @@ bool GdbEngine::hasCapability(unsigned cap) const | AddWatcherCapability | WatchWidgetsCapability | ShowModuleSymbolsCapability + | ShowModuleSectionsCapability | CatchCapability | OperateByInstructionCapability | RunToLineCapability @@ -3325,7 +3326,7 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response) const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0); const QString fileName = cookie.section(QLatin1Char('@'), 1, 1); if (response.resultClass == GdbResultDone) { - Symbols rc; + Symbols symbols; QFile file(fileName); file.open(QIODevice::ReadOnly); // Object file /opt/dev/qt/lib/libQtNetworkMyns.so.4: @@ -3369,17 +3370,62 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response) symbol.name = _(line.mid(posName, lenName)); symbol.section = _(line.mid(posSection, lenSection)); symbol.demangled = _(line.mid(posDemangled, lenDemangled)); - rc.push_back(symbol); + symbols.push_back(symbol); } file.close(); file.remove(); - debuggerCore()->showModuleSymbols(modulePath, rc); + debuggerCore()->showModuleSymbols(modulePath, symbols); } else { showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"), tr("Cannot read symbols for module \"%1\".").arg(fileName)); } } +void GdbEngine::requestModuleSections(const QString &moduleName) +{ + // There seems to be no way to get the symbols from a single .so. + postCommand("maint info section ALLOBJ", + NeedsStop, CB(handleShowModuleSections), moduleName); +} + +void GdbEngine::handleShowModuleSections(const GdbResponse &response) +{ + // ~" Object file: /usr/lib/i386-linux-gnu/libffi.so.6\n" + // ~" 0xb44a6114->0xb44a6138 at 0x00000114: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS\n" + if (response.resultClass == GdbResultDone) { + const QString moduleName = response.cookie.toString(); + const QStringList lines = QString::fromLocal8Bit(response.consoleStreamOutput).split(QLatin1Char('\n')); + const QString prefix = QLatin1String(" Object file: "); + const QString needle = prefix + moduleName; + Sections sections; + bool active = false; + foreach (const QString &line, lines) { + if (line.startsWith(prefix)) { + if (active) + break; + if (line == needle) + active = true; + } else { + if (active) { + QStringList items = line.split(QLatin1Char(' '), QString::SkipEmptyParts); + QString fromTo = items.value(0, QString()); + const int pos = fromTo.indexOf(QLatin1Char('-')); + QTC_ASSERT(pos >= 0, continue); + Section section; + section.from = fromTo.left(pos); + section.to = fromTo.mid(pos + 2); + section.address = items.value(2, QString()); + section.name = items.value(3, QString()); + section.flags = items.value(4, QString()); + sections.append(section); + } + } + } + if (!sections.isEmpty()) + debuggerCore()->showModuleSections(moduleName, sections); + } +} + void GdbEngine::reloadModules() { if (state() == InferiorRunOk || state() == InferiorStopOk) diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 8ad58469209..25b687554b6 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -476,11 +476,13 @@ private: ////////// View & Data Stuff ////////// Q_SLOT void loadAllSymbols(); void loadSymbolsForStack(); void requestModuleSymbols(const QString &moduleName); + void requestModuleSections(const QString &moduleName); void reloadModules(); void examineModules(); void reloadModulesInternal(); void handleModulesList(const GdbResponse &response); void handleShowModuleSymbols(const GdbResponse &response); + void handleShowModuleSections(const GdbResponse &response); // // Snapshot specific stuff diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h index f72c34e016a..1b71c1b633c 100644 --- a/src/plugins/debugger/moduleshandler.h +++ b/src/plugins/debugger/moduleshandler.h @@ -68,6 +68,24 @@ typedef QVector<Symbol> Symbols; ////////////////////////////////////////////////////////////////// // +// Section +// +////////////////////////////////////////////////////////////////// + +class Section +{ +public: + QString from; + QString to; + QString address; + QString name; + QString flags; +}; + +typedef QVector<Section> Sections; + +////////////////////////////////////////////////////////////////// +// // Module // ////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp index 3c856c3967e..05e0dc383ef 100644 --- a/src/plugins/debugger/moduleswindow.cpp +++ b/src/plugins/debugger/moduleswindow.cpp @@ -112,6 +112,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) QAction *actLoadSymbolsForModule = 0; QAction *actEditFile = 0; QAction *actShowModuleSymbols = 0; + QAction *actShowModuleSections = 0; QAction *actShowDependencies = 0; // Show dependencies by running 'depends.exe' if (name.isEmpty()) { actLoadSymbolsForModule = new QAction(tr("Load Symbols for Module"), &menu); @@ -120,6 +121,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) actEditFile->setEnabled(false); actShowModuleSymbols = new QAction(tr("Show Symbols"), &menu); actShowModuleSymbols->setEnabled(false); + actShowModuleSections = new QAction(tr("Show Sections"), &menu); + actShowModuleSections->setEnabled(false); actShowDependencies = new QAction(tr("Show Dependencies"), &menu); actShowDependencies->setEnabled(false); } else { @@ -131,6 +134,9 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) actShowModuleSymbols = new QAction(tr("Show Symbols in File \"%1\"").arg(name), &menu); actShowModuleSymbols->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability)); + actShowModuleSections + = new QAction(tr("Show Sections in File \"%1\"").arg(name), &menu); + actShowModuleSections->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability)); actShowDependencies = new QAction(tr("Show Dependencies of \"%1\"").arg(name), &menu); actShowDependencies->setEnabled(!fileName.isEmpty()); if (!Utils::HostOsInfo::isWindowsHost()) @@ -146,6 +152,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) menu.addAction(actLoadSymbolsForModule); menu.addAction(actEditFile); menu.addAction(actShowModuleSymbols); + menu.addAction(actShowModuleSections); addBaseContextActions(&menu); QAction *act = menu.exec(ev->globalPos()); @@ -164,6 +171,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev) engine->gotoLocation(fileName); else if (act == actShowModuleSymbols) engine->requestModuleSymbols(fileName); + else if (act == actShowModuleSections) + engine->requestModuleSections(fileName); else if (actShowDependencies && act == actShowDependencies) QProcess::startDetached(QLatin1String("depends"), QStringList(fileName)); else |