debugger: more modulehandler polishing

Change-Id: I2382a597783512b566118cccf772ff530cdf9026
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
hjk
2012-06-02 03:30:21 +02:00
parent e6d4904a62
commit 0394699a4c
5 changed files with 121 additions and 48 deletions

View File

@@ -117,18 +117,21 @@ QString DumperHelper::msgPtraceError(DebuggerStartMode sm)
{ {
if (sm == StartInternal) { if (sm == StartInternal) {
return QCoreApplication::translate("QtDumperHelper", return QCoreApplication::translate("QtDumperHelper",
"ptrace: Operation not permitted.\n\n" "ptrace: Operation not permitted.\n\n"
"Could not attach to the process. Check the settings of\n" "Could not attach to the process. "
"/proc/sys/kernel/yama/ptrace_scope\n" "Make sure no other debugger traces this process.\n"
"For more details, see/etc/sysctl.d/10-ptrace.conf\n"); "Check the settings of\n"
} else { "/proc/sys/kernel/yama/ptrace_scope\n"
return QCoreApplication::translate("QtDumperHelper", "For more details, see /etc/sysctl.d/10-ptrace.conf\n");
"ptrace: Operation not permitted.\n\n"
"Could not attach to the process. If your uid matches the uid\n"
"of the target process, check the settings of\n"
"/proc/sys/kernel/yama/ptrace_scope\n"
"For more details, see/etc/sysctl.d/10-ptrace.conf\n");
} }
return QCoreApplication::translate("QtDumperHelper",
"ptrace: Operation not permitted.\n\n"
"Could not attach to the process. "
"Make sure no other debugger traces this process.\n"
"If your uid matches the uid\n"
"of the target process, check the settings of\n"
"/proc/sys/kernel/yama/ptrace_scope\n"
"For more details, see /etc/sysctl.d/10-ptrace.conf\n");
} }
static inline void formatQtVersion(int v, QTextStream &str) static inline void formatQtVersion(int v, QTextStream &str)

View File

@@ -483,11 +483,24 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// target-name="/usr/lib/libdrm.so.2", // target-name="/usr/lib/libdrm.so.2",
// host-name="/usr/lib/libdrm.so.2", // host-name="/usr/lib/libdrm.so.2",
// symbols-loaded="0" // symbols-loaded="0"
// id="/lib/i386-linux-gnu/libc.so.6"
// target-name="/lib/i386-linux-gnu/libc.so.6"
// host-name="/lib/i386-linux-gnu/libc.so.6"
// symbols-loaded="0",thread-group="i1"
QByteArray id = result.findChild("id").data(); QByteArray id = result.findChild("id").data();
if (!id.isEmpty()) if (!id.isEmpty())
showStatusMessage(tr("Library %1 loaded").arg(_(id)), 1000); showStatusMessage(tr("Library %1 loaded").arg(_(id)), 1000);
progressPing(); progressPing();
invalidateSourcesList(); invalidateSourcesList();
Module module;
module.startAddress = 0;
module.endAddress = 0;
module.hostPath = _(result.findChild("host-name").data());
module.modulePath = _(result.findChild("target-name").data());
module.moduleName = QFileInfo(module.hostPath).baseName();
examineModule(&module);
modulesHandler()->addModule(module);
} else if (asyncClass == "library-unloaded") { } else if (asyncClass == "library-unloaded") {
// Archer has 'id="/usr/lib/libdrm.so.2", // Archer has 'id="/usr/lib/libdrm.so.2",
// target-name="/usr/lib/libdrm.so.2", // target-name="/usr/lib/libdrm.so.2",
@@ -1676,10 +1689,6 @@ void GdbEngine::handleStop2(const GdbMi &data)
isStopperThread = true; isStopperThread = true;
} }
// This is for display only.
if (m_modulesListOutdated)
reloadModulesInternal();
if (m_breakListOutdated) { if (m_breakListOutdated) {
reloadBreakListInternal(); reloadBreakListInternal();
} else { } else {
@@ -3353,7 +3362,7 @@ void GdbEngine::loadSymbolsForStack()
} }
} }
if (needUpdate) { if (needUpdate) {
reloadModulesInternal(); //reloadModulesInternal();
reloadBreakListInternal(); reloadBreakListInternal();
reloadStack(true); reloadStack(true);
updateLocals(); updateLocals();
@@ -3442,7 +3451,6 @@ void GdbEngine::reloadModules()
void GdbEngine::reloadModulesInternal() void GdbEngine::reloadModulesInternal()
{ {
m_modulesListOutdated = false;
postCommand("info shared", NeedsStop, CB(handleModulesList)); postCommand("info shared", NeedsStop, CB(handleModulesList));
} }
@@ -3453,15 +3461,16 @@ static QString nameFromPath(const QString &path)
void GdbEngine::handleModulesList(const GdbResponse &response) void GdbEngine::handleModulesList(const GdbResponse &response)
{ {
Modules modules;
if (response.resultClass == GdbResultDone) { if (response.resultClass == GdbResultDone) {
ModulesHandler *handler = modulesHandler();
Module module;
// That's console-based output, likely Linux or Windows, // That's console-based output, likely Linux or Windows,
// but we can avoid the target dependency here. // but we can avoid the target dependency here.
QString data = QString::fromLocal8Bit(response.consoleStreamOutput); QString data = QString::fromLocal8Bit(response.consoleStreamOutput);
QTextStream ts(&data, QIODevice::ReadOnly); QTextStream ts(&data, QIODevice::ReadOnly);
bool found = false;
while (!ts.atEnd()) { while (!ts.atEnd()) {
QString line = ts.readLine(); QString line = ts.readLine();
Module module;
QString symbolsRead; QString symbolsRead;
QTextStream ts(&line, QIODevice::ReadOnly); QTextStream ts(&line, QIODevice::ReadOnly);
if (line.startsWith(QLatin1String("0x"))) { if (line.startsWith(QLatin1String("0x"))) {
@@ -3470,7 +3479,9 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
module.moduleName = nameFromPath(module.modulePath); module.moduleName = nameFromPath(module.modulePath);
module.symbolsRead = module.symbolsRead =
(symbolsRead == QLatin1String("Yes") ? Module::ReadOk : Module::ReadFailed); (symbolsRead == QLatin1String("Yes") ? Module::ReadOk : Module::ReadFailed);
modules.append(module); examineModule(&module);
handler->updateModule(module);
found = true;
} else if (line.trimmed().startsWith(QLatin1String("No"))) { } else if (line.trimmed().startsWith(QLatin1String("No"))) {
// gdb 6.4 symbianelf // gdb 6.4 symbianelf
ts >> symbolsRead; ts >> symbolsRead;
@@ -3479,17 +3490,18 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
module.endAddress = 0; module.endAddress = 0;
module.modulePath = ts.readLine().trimmed(); module.modulePath = ts.readLine().trimmed();
module.moduleName = nameFromPath(module.modulePath); module.moduleName = nameFromPath(module.modulePath);
modules.append(module); examineModule(&module);
handler->updateModule(module);
found = true;
} }
} }
if (modules.isEmpty()) { if (!found) {
// Mac has^done,shlib-info={num="1",name="dyld",kind="-", // Mac has^done,shlib-info={num="1",name="dyld",kind="-",
// dyld-addr="0x8fe00000",reason="dyld",requested-state="Y", // dyld-addr="0x8fe00000",reason="dyld",requested-state="Y",
// state="Y",path="/usr/lib/dyld",description="/usr/lib/dyld", // state="Y",path="/usr/lib/dyld",description="/usr/lib/dyld",
// loaded_addr="0x8fe00000",slide="0x0",prefix="__dyld_"}, // loaded_addr="0x8fe00000",slide="0x0",prefix="__dyld_"},
// shlib-info={...}... // shlib-info={...}...
foreach (const GdbMi &item, response.data.children()) { foreach (const GdbMi &item, response.data.children()) {
Module module;
module.modulePath = module.modulePath =
QString::fromLocal8Bit(item.findChild("path").data()); QString::fromLocal8Bit(item.findChild("path").data());
module.moduleName = nameFromPath(module.modulePath); module.moduleName = nameFromPath(module.modulePath);
@@ -3498,25 +3510,34 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
module.startAddress = module.startAddress =
item.findChild("loaded_addr").data().toULongLong(0, 0); item.findChild("loaded_addr").data().toULongLong(0, 0);
module.endAddress = 0; // FIXME: End address not easily available. module.endAddress = 0; // FIXME: End address not easily available.
modules.append(module); examineModule(&module);
handler->updateModule(module);
} }
} }
} }
modulesHandler()->setModules(modules); }
void GdbEngine::examineModule(Module *module)
{
Utils::ElfReader reader(module->modulePath);
QList<QByteArray> names = reader.sectionNames();
if (names.contains(".gdb_index"))
module->symbolsType = Module::FastSymbols;
else if (names.contains(".debug_inf"))
module->symbolsType = Module::PlainSymbols;
else if (names.contains(".gnu_debuglink"))
module->symbolsType = Module::SeparateSymbols;
else
module->symbolsType = Module::NoSymbols;
} }
void GdbEngine::examineModules() void GdbEngine::examineModules()
{ {
ModulesHandler *handler = modulesHandler(); ModulesHandler *handler = modulesHandler();
foreach (Module module, handler->modules()) { foreach (Module module, handler->modules()) {
if (module.symbolsType == Module::UnknownType) { if (module.symbolsType == Module::UnknownSymbols) {
Utils::ElfReader reader(module.modulePath); examineModule(&module);
QList<QByteArray> names = reader.sectionNames(); modulesHandler()->updateModule(module);
if (names.contains(".gdb_index"))
module.symbolsType = Module::FastSymbols;
else
module.symbolsType = Module::PlainSymbols;
handler->updateModule(module);
} }
} }
} }
@@ -3529,7 +3550,6 @@ void GdbEngine::examineModules()
void GdbEngine::invalidateSourcesList() void GdbEngine::invalidateSourcesList()
{ {
m_modulesListOutdated = true;
m_breakListOutdated = true; m_breakListOutdated = true;
} }
@@ -5003,6 +5023,13 @@ void GdbEngine::handleAdapterStarted()
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("ADAPTER SUCCESSFULLY STARTED")); showMessage(_("ADAPTER SUCCESSFULLY STARTED"));
notifyEngineSetupOk(); notifyEngineSetupOk();
Module module;
module.startAddress = 0;
module.endAddress = 0;
module.modulePath = startParameters().executable;
module.moduleName = QLatin1String("<executable>");
modulesHandler()->addModule(module);
} }
void GdbEngine::setupInferior() void GdbEngine::setupInferior()
@@ -5363,6 +5390,7 @@ void GdbEngine::checkForReleaseBuild()
interesting.append(".gdb_index"); interesting.append(".gdb_index");
interesting.append(".note.gnu.build-id"); interesting.append(".note.gnu.build-id");
interesting.append(".gnu.hash"); interesting.append(".gnu.hash");
interesting.append(".gnu_debuglink");
} }
QSet<QByteArray> seen; QSet<QByteArray> seen;

View File

@@ -63,6 +63,7 @@ class DebugInfoTaskHandler;
class GdbResponse; class GdbResponse;
class GdbMi; class GdbMi;
class GdbToolTipContext; class GdbToolTipContext;
class Module;
class WatchData; class WatchData;
class DisassemblerAgentCookie; class DisassemblerAgentCookie;
@@ -513,12 +514,11 @@ private: ////////// View & Data Stuff //////////
void requestModuleSymbols(const QString &moduleName); void requestModuleSymbols(const QString &moduleName);
void reloadModules(); void reloadModules();
void examineModules(); void examineModules();
void examineModule(Module *module);
void reloadModulesInternal(); void reloadModulesInternal();
void handleModulesList(const GdbResponse &response); void handleModulesList(const GdbResponse &response);
void handleShowModuleSymbols(const GdbResponse &response); void handleShowModuleSymbols(const GdbResponse &response);
bool m_modulesListOutdated;
// //
// Snapshot specific stuff // Snapshot specific stuff
// //

View File

@@ -124,15 +124,51 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const
case 3: case 3:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
switch (module.symbolsType) { switch (module.symbolsType) {
case Module::UnknownType: return ModulesHandler::tr("unknown"); case Module::UnknownSymbols:
case Module::PlainSymbols: return ModulesHandler::tr("plain"); return ModulesHandler::tr("unknown");
case Module::FastSymbols: return ModulesHandler::tr("fast"); case Module::NoSymbols:
return ModulesHandler::tr("none");
case Module::PlainSymbols:
return ModulesHandler::tr("plain");
case Module::FastSymbols:
return ModulesHandler::tr("fast");
case Module::SeparateSymbols:
return ModulesHandler::tr("separate");
}
else if (role == Qt::ToolTipRole)
switch (module.symbolsType) {
case Module::UnknownSymbols:
return ModulesHandler::tr(
"It is unknown whether this module contains debug "
"information.\nUse \"Examine Symbols\" from the "
"context menu to initiate a check.");
case Module::NoSymbols:
return ModulesHandler::tr(
"This module neither contains nor references debug "
"information.\nStepping into the module or setting "
"breakpoints by file and line will not work.");
case Module::PlainSymbols:
return ModulesHandler::tr(
"This module contains debug information.\nStepping "
"into the module or setting breakpoints by file and "
"is expected to work.");
case Module::FastSymbols:
return ModulesHandler::tr(
"This module contains debug information.\nStepping "
"into the module or setting breakpoints by file and "
"is expected to work.");
case Module::SeparateSymbols:
return ModulesHandler::tr(
"This module does not contains debug information "
"itself, but contains a reference to external "
"debug information.");
} }
break; break;
case 4: case 4:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return QString(QLatin1String("0x") if (module.startAddress)
+ QString::number(module.startAddress, 16)); return QString(QLatin1String("0x")
+ QString::number(module.startAddress, 16));
break; break;
case 5: case 5:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
@@ -189,9 +225,12 @@ void ModulesModel::removeModule(const QString &modulePath)
void ModulesModel::updateModule(const Module &module) void ModulesModel::updateModule(const Module &module)
{ {
const int row = indexOfModule(module.modulePath); const int row = indexOfModule(module.modulePath);
QTC_ASSERT(row != -1, return); if (row == -1) {
m_modules[row] = module; addModule(module);
dataChanged(index(row, 0, QModelIndex()), index(row, 4, QModelIndex())); } else {
m_modules[row] = module;
dataChanged(index(row, 0, QModelIndex()), index(row, 4, QModelIndex()));
}
} }
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////

View File

@@ -73,21 +73,24 @@ typedef QVector<Symbol> Symbols;
class Module class Module
{ {
public: public:
Module() : symbolsRead(UnknownReadState), symbolsType(UnknownType) {} Module() : symbolsRead(UnknownReadState), symbolsType(UnknownSymbols) {}
public: public:
enum SymbolReadState { enum SymbolReadState {
UnknownReadState, // Not tried. UnknownReadState, // Not tried.
ReadFailed, // Tried to read, but failed. ReadFailed, // Tried to read, but failed.
ReadOk // Dwarf index available. ReadOk // Dwarf index available.
}; };
enum SymbolType { enum SymbolType {
UnknownType, // Unknown. UnknownSymbols, // Unknown.
NoSymbols, // No usable symbols.
SeparateSymbols, // Symbols mentioned, but not in binary.
PlainSymbols, // Ordinary symbols available. PlainSymbols, // Ordinary symbols available.
FastSymbols // Dwarf index available. FastSymbols // Dwarf index available.
}; };
QString moduleName; QString moduleName;
QString modulePath; QString modulePath;
QString hostPath;
SymbolReadState symbolsRead; SymbolReadState symbolsRead;
SymbolType symbolsType; SymbolType symbolsType;
quint64 startAddress; quint64 startAddress;