forked from qt-creator/qt-creator
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 <qthjk@ovi.com>
This commit is contained in:
@@ -167,7 +167,8 @@ enum DebuggerCapabilities
|
|||||||
CatchCapability = 0x200000, //!< fork, vfork, syscall
|
CatchCapability = 0x200000, //!< fork, vfork, syscall
|
||||||
OperateByInstructionCapability = 0x400000,
|
OperateByInstructionCapability = 0x400000,
|
||||||
RunToLineCapability = 0x800000,
|
RunToLineCapability = 0x800000,
|
||||||
MemoryAddressCapability = 0x1000000
|
MemoryAddressCapability = 0x1000000,
|
||||||
|
ShowModuleSectionsCapability = 0x200000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LogChannel
|
enum LogChannel
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ namespace Internal {
|
|||||||
class BreakHandler;
|
class BreakHandler;
|
||||||
class SnapshotHandler;
|
class SnapshotHandler;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
|
class Section;
|
||||||
class DebuggerToolTipManager;
|
class DebuggerToolTipManager;
|
||||||
class GlobalDebuggerOptions;
|
class GlobalDebuggerOptions;
|
||||||
|
|
||||||
@@ -113,6 +114,8 @@ public:
|
|||||||
// DebuggerEngineType et = NoEngineType) const = 0;
|
// DebuggerEngineType et = NoEngineType) const = 0;
|
||||||
virtual void showModuleSymbols(const QString &moduleName,
|
virtual void showModuleSymbols(const QString &moduleName,
|
||||||
const QVector<Symbol> &symbols) = 0;
|
const QVector<Symbol> &symbols) = 0;
|
||||||
|
virtual void showModuleSections(const QString &moduleName,
|
||||||
|
const QVector<Section> §ions) = 0;
|
||||||
virtual void openMemoryEditor() = 0;
|
virtual void openMemoryEditor() = 0;
|
||||||
virtual void languagesChanged() = 0;
|
virtual void languagesChanged() = 0;
|
||||||
virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) = 0;
|
virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) = 0;
|
||||||
|
|||||||
@@ -1451,6 +1451,10 @@ void DebuggerEngine::requestModuleSymbols(const QString &)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerEngine::requestModuleSections(const QString &)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerEngine::reloadRegisters()
|
void DebuggerEngine::reloadRegisters()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public:
|
|||||||
virtual void loadSymbolsForStack();
|
virtual void loadSymbolsForStack();
|
||||||
virtual void loadAllSymbols();
|
virtual void loadAllSymbols();
|
||||||
virtual void requestModuleSymbols(const QString &moduleName);
|
virtual void requestModuleSymbols(const QString &moduleName);
|
||||||
|
virtual void requestModuleSections(const QString &moduleName);
|
||||||
|
|
||||||
virtual void reloadRegisters();
|
virtual void reloadRegisters();
|
||||||
virtual void reloadSourceFiles();
|
virtual void reloadSourceFiles();
|
||||||
|
|||||||
@@ -1220,6 +1220,7 @@ public slots:
|
|||||||
QString stringSetting(int code) const;
|
QString stringSetting(int code) const;
|
||||||
|
|
||||||
void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
|
void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
|
||||||
|
void showModuleSections(const QString &moduleName, const Sections §ions);
|
||||||
|
|
||||||
bool parseArgument(QStringList::const_iterator &it,
|
bool parseArgument(QStringList::const_iterator &it,
|
||||||
const QStringList::const_iterator &cend, QString *errorMessage);
|
const QStringList::const_iterator &cend, QString *errorMessage);
|
||||||
@@ -3327,6 +3328,36 @@ void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName,
|
|||||||
createNewDock(w);
|
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()
|
void DebuggerPluginPrivate::aboutToShutdown()
|
||||||
{
|
{
|
||||||
m_plugin->removeObject(this);
|
m_plugin->removeObject(this);
|
||||||
|
|||||||
@@ -2128,6 +2128,7 @@ bool GdbEngine::hasCapability(unsigned cap) const
|
|||||||
| AddWatcherCapability
|
| AddWatcherCapability
|
||||||
| WatchWidgetsCapability
|
| WatchWidgetsCapability
|
||||||
| ShowModuleSymbolsCapability
|
| ShowModuleSymbolsCapability
|
||||||
|
| ShowModuleSectionsCapability
|
||||||
| CatchCapability
|
| CatchCapability
|
||||||
| OperateByInstructionCapability
|
| OperateByInstructionCapability
|
||||||
| RunToLineCapability
|
| RunToLineCapability
|
||||||
@@ -3325,7 +3326,7 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response)
|
|||||||
const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0);
|
const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0);
|
||||||
const QString fileName = cookie.section(QLatin1Char('@'), 1, 1);
|
const QString fileName = cookie.section(QLatin1Char('@'), 1, 1);
|
||||||
if (response.resultClass == GdbResultDone) {
|
if (response.resultClass == GdbResultDone) {
|
||||||
Symbols rc;
|
Symbols symbols;
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
// Object file /opt/dev/qt/lib/libQtNetworkMyns.so.4:
|
// 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.name = _(line.mid(posName, lenName));
|
||||||
symbol.section = _(line.mid(posSection, lenSection));
|
symbol.section = _(line.mid(posSection, lenSection));
|
||||||
symbol.demangled = _(line.mid(posDemangled, lenDemangled));
|
symbol.demangled = _(line.mid(posDemangled, lenDemangled));
|
||||||
rc.push_back(symbol);
|
symbols.push_back(symbol);
|
||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
file.remove();
|
file.remove();
|
||||||
debuggerCore()->showModuleSymbols(modulePath, rc);
|
debuggerCore()->showModuleSymbols(modulePath, symbols);
|
||||||
} else {
|
} else {
|
||||||
showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"),
|
showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"),
|
||||||
tr("Cannot read symbols for module \"%1\".").arg(fileName));
|
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()
|
void GdbEngine::reloadModules()
|
||||||
{
|
{
|
||||||
if (state() == InferiorRunOk || state() == InferiorStopOk)
|
if (state() == InferiorRunOk || state() == InferiorStopOk)
|
||||||
|
|||||||
@@ -476,11 +476,13 @@ private: ////////// View & Data Stuff //////////
|
|||||||
Q_SLOT void loadAllSymbols();
|
Q_SLOT void loadAllSymbols();
|
||||||
void loadSymbolsForStack();
|
void loadSymbolsForStack();
|
||||||
void requestModuleSymbols(const QString &moduleName);
|
void requestModuleSymbols(const QString &moduleName);
|
||||||
|
void requestModuleSections(const QString &moduleName);
|
||||||
void reloadModules();
|
void reloadModules();
|
||||||
void examineModules();
|
void examineModules();
|
||||||
void reloadModulesInternal();
|
void reloadModulesInternal();
|
||||||
void handleModulesList(const GdbResponse &response);
|
void handleModulesList(const GdbResponse &response);
|
||||||
void handleShowModuleSymbols(const GdbResponse &response);
|
void handleShowModuleSymbols(const GdbResponse &response);
|
||||||
|
void handleShowModuleSections(const GdbResponse &response);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Snapshot specific stuff
|
// Snapshot specific stuff
|
||||||
|
|||||||
@@ -66,6 +66,24 @@ public:
|
|||||||
|
|
||||||
typedef QVector<Symbol> Symbols;
|
typedef QVector<Symbol> Symbols;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Section
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Section
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString from;
|
||||||
|
QString to;
|
||||||
|
QString address;
|
||||||
|
QString name;
|
||||||
|
QString flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QVector<Section> Sections;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Module
|
// Module
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
QAction *actLoadSymbolsForModule = 0;
|
QAction *actLoadSymbolsForModule = 0;
|
||||||
QAction *actEditFile = 0;
|
QAction *actEditFile = 0;
|
||||||
QAction *actShowModuleSymbols = 0;
|
QAction *actShowModuleSymbols = 0;
|
||||||
|
QAction *actShowModuleSections = 0;
|
||||||
QAction *actShowDependencies = 0; // Show dependencies by running 'depends.exe'
|
QAction *actShowDependencies = 0; // Show dependencies by running 'depends.exe'
|
||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
actLoadSymbolsForModule = new QAction(tr("Load Symbols for Module"), &menu);
|
actLoadSymbolsForModule = new QAction(tr("Load Symbols for Module"), &menu);
|
||||||
@@ -120,6 +121,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
actEditFile->setEnabled(false);
|
actEditFile->setEnabled(false);
|
||||||
actShowModuleSymbols = new QAction(tr("Show Symbols"), &menu);
|
actShowModuleSymbols = new QAction(tr("Show Symbols"), &menu);
|
||||||
actShowModuleSymbols->setEnabled(false);
|
actShowModuleSymbols->setEnabled(false);
|
||||||
|
actShowModuleSections = new QAction(tr("Show Sections"), &menu);
|
||||||
|
actShowModuleSections->setEnabled(false);
|
||||||
actShowDependencies = new QAction(tr("Show Dependencies"), &menu);
|
actShowDependencies = new QAction(tr("Show Dependencies"), &menu);
|
||||||
actShowDependencies->setEnabled(false);
|
actShowDependencies->setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
@@ -131,6 +134,9 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
actShowModuleSymbols
|
actShowModuleSymbols
|
||||||
= new QAction(tr("Show Symbols in File \"%1\"").arg(name), &menu);
|
= new QAction(tr("Show Symbols in File \"%1\"").arg(name), &menu);
|
||||||
actShowModuleSymbols->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability));
|
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 = new QAction(tr("Show Dependencies of \"%1\"").arg(name), &menu);
|
||||||
actShowDependencies->setEnabled(!fileName.isEmpty());
|
actShowDependencies->setEnabled(!fileName.isEmpty());
|
||||||
if (!Utils::HostOsInfo::isWindowsHost())
|
if (!Utils::HostOsInfo::isWindowsHost())
|
||||||
@@ -146,6 +152,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
menu.addAction(actLoadSymbolsForModule);
|
menu.addAction(actLoadSymbolsForModule);
|
||||||
menu.addAction(actEditFile);
|
menu.addAction(actEditFile);
|
||||||
menu.addAction(actShowModuleSymbols);
|
menu.addAction(actShowModuleSymbols);
|
||||||
|
menu.addAction(actShowModuleSections);
|
||||||
addBaseContextActions(&menu);
|
addBaseContextActions(&menu);
|
||||||
|
|
||||||
QAction *act = menu.exec(ev->globalPos());
|
QAction *act = menu.exec(ev->globalPos());
|
||||||
@@ -164,6 +171,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
|||||||
engine->gotoLocation(fileName);
|
engine->gotoLocation(fileName);
|
||||||
else if (act == actShowModuleSymbols)
|
else if (act == actShowModuleSymbols)
|
||||||
engine->requestModuleSymbols(fileName);
|
engine->requestModuleSymbols(fileName);
|
||||||
|
else if (act == actShowModuleSections)
|
||||||
|
engine->requestModuleSections(fileName);
|
||||||
else if (actShowDependencies && act == actShowDependencies)
|
else if (actShowDependencies && act == actShowDependencies)
|
||||||
QProcess::startDetached(QLatin1String("depends"), QStringList(fileName));
|
QProcess::startDetached(QLatin1String("depends"), QStringList(fileName));
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user