debugger: polish module symbols

This commit is contained in:
hjk
2010-11-26 09:58:34 +01:00
parent a9f825fc2e
commit 7d8d51677b
16 changed files with 173 additions and 106 deletions

View File

@@ -1777,14 +1777,19 @@ void GdbEngine::setupEngine()
unsigned GdbEngine::debuggerCapabilities() const
{
unsigned caps = ReverseSteppingCapability
| AutoDerefPointersCapability | DisassemblerCapability
| RegisterCapability | ShowMemoryCapability
| JumpToLineCapability | ReloadModuleCapability
| ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability
| AutoDerefPointersCapability
| DisassemblerCapability
| RegisterCapability
| ShowMemoryCapability
| JumpToLineCapability
| ReloadModuleCapability
| ReloadModuleSymbolsCapability
| BreakOnThrowAndCatchCapability
| ReturnFromFunctionCapability
| CreateFullBacktraceCapability
| WatchpointCapability
| AddWatcherCapability;
| AddWatcherCapability
| ShowModuleSymbolsCapability;
if (startParameters().startMode == AttachCore)
return caps;
@@ -2723,36 +2728,76 @@ void GdbEngine::loadAllSymbols()
void GdbEngine::requestModuleSymbols(const QString &moduleName)
{
QList<Symbol> rc;
bool success = false;
QString errorMessage;
do {
const QString nmBinary = _("nm");
QProcess proc;
proc.start(nmBinary, QStringList() << _("-D") << moduleName);
if (!proc.waitForFinished()) {
errorMessage = tr("Unable to run '%1': %2").arg(nmBinary, proc.errorString());
break;
}
const QString contents = QString::fromLocal8Bit(proc.readAllStandardOutput());
const QRegExp re(_("([0-9a-f]+)?\\s+([^\\s]+)\\s+([^\\s]+)"));
Q_ASSERT(re.isValid());
foreach (const QString &line, contents.split(_c('\n'))) {
if (re.indexIn(line) != -1) {
Symbol symbol;
symbol.address = re.cap(1);
symbol.state = re.cap(2);
symbol.name = re.cap(3);
rc.push_back(symbol);
QTemporaryFile tf(QDir::tempPath() + _("/gdbsymbols"));
if (!tf.open())
return;
QString fileName = tf.fileName();
tf.close();
postCommand("maint print msymbols " + fileName.toLocal8Bit()
+ " " + moduleName.toLocal8Bit(),
NeedsStop, CB(handleShowModuleSymbols),
QVariant(moduleName + QLatin1Char('@') + fileName));
}
void GdbEngine::handleShowModuleSymbols(const GdbResponse &response)
{
const QString cookie = response.cookie.toString();
const QString moduleName = cookie.section(QLatin1Char('@'), 0, 0);
const QString fileName = cookie.section(QLatin1Char('@'), 1, 1);
if (response.resultClass == GdbResultDone) {
Symbols rc;
QFile file(fileName);
file.open(QIODevice::ReadOnly);
// Object file /opt/dev/qt/lib/libQtNetworkMyns.so.4:
// [ 0] A 0x16bd64 _DYNAMIC moc_qudpsocket.cpp
// [12] S 0xe94680 _ZN4myns5QFileC1Ev section .plt myns::QFile::QFile()
foreach (const QByteArray &line, file.readAll().split('\n')) {
if (line.isEmpty())
continue;
if (!line.at(0) == '[')
continue;
int posCode = line.indexOf(']') + 2;
int posAddress = line.indexOf("0x", posCode);
if (posAddress == -1)
continue;
int posName = line.indexOf(" ", posAddress);
int lenAddress = posName - posAddress - 1;
int posSection = line.indexOf(" section ");
int lenName = 0;
int lenSection = 0;
int posDemangled = 0;
if (posSection == -1) {
lenName = line.size() - posName;
posDemangled = posName;
} else {
qWarning("moduleSymbols: unhandled: %s", qPrintable(line));
lenName = posSection - posName;
posSection += 10;
posDemangled = line.indexOf(' ', posSection + 1);
if (posDemangled == -1) {
lenSection = line.size() - posSection;
} else {
lenSection = posDemangled - posSection;
posDemangled += 1;
}
}
int lenDemangled = 0;
if (posDemangled != -1)
lenDemangled = line.size() - posDemangled;
Symbol symbol;
symbol.state = _(line.mid(posCode, 1));
symbol.address = _(line.mid(posAddress, lenAddress));
symbol.name = _(line.mid(posName, lenName));
symbol.section = _(line.mid(posSection, lenSection));
symbol.demangled = _(line.mid(posDemangled, lenDemangled));
rc.push_back(symbol);
}
success = true;
} while (false);
if (!success)
qWarning("moduleSymbols: %s\n", qPrintable(errorMessage));
showModuleSymbols(moduleName, rc);
file.close();
file.remove();
debuggerCore()->showModuleSymbols(moduleName, rc);
} else {
showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"),
tr("Cannot read symbols for module \"%1\".").arg(fileName));
}
}
void GdbEngine::reloadModules()
@@ -2773,7 +2818,7 @@ void GdbEngine::reloadModulesInternal()
void GdbEngine::handleModulesList(const GdbResponse &response)
{
QList<Module> modules;
Modules modules;
if (response.resultClass == GdbResultDone) {
// That's console-based output, likely Linux or Windows,
// but we can avoid the #ifdef here.