aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhjk <[email protected]>2012-11-07 18:31:17 +0100
committerhjk <[email protected]>2012-11-09 11:44:22 +0100
commit6841976aa81cbbf21af7a4c15dd3823d39d5016b (patch)
tree3f9b67d846b3dc09b4ee945db4b693a246367d72
parent6c6400b7b8137340a27c4fc92e3a15dfc27e1f2c (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]>
-rw-r--r--src/plugins/debugger/debuggerconstants.h3
-rw-r--r--src/plugins/debugger/debuggercore.h3
-rw-r--r--src/plugins/debugger/debuggerengine.cpp4
-rw-r--r--src/plugins/debugger/debuggerengine.h1
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp31
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp52
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h2
-rw-r--r--src/plugins/debugger/moduleshandler.h18
-rw-r--r--src/plugins/debugger/moduleswindow.cpp9
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> &sections) = 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 &sections);
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 &sections)
+{
+ 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