Commit 278d9092 authored by hjk's avatar hjk Committed by hjk
Browse files

debugger: use the elfreader instead of external objdump



Change-Id: Ic5c5525703a6ef8924ac68e1a9ed33e411aada08
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 1e31ae20
...@@ -388,6 +388,12 @@ DebuggerSettings::DebuggerSettings(QSettings *settings) ...@@ -388,6 +388,12 @@ DebuggerSettings::DebuggerSettings(QSettings *settings)
item->setValue(false); item->setValue(false);
insertItem(TargetAsync, item); insertItem(TargetAsync, item);
item = new SavedAction(this);
item->setSettingsKey(debugModeGroup, QLatin1String("WarnOnReleaseBuilds"));
item->setCheckable(true);
item->setDefaultValue(true);
insertItem(WarnOnReleaseBuilds, item);
item = new SavedAction(this); item = new SavedAction(this);
item->setSettingsKey(debugModeGroup, QLatin1String("GdbStartupCommands")); item->setSettingsKey(debugModeGroup, QLatin1String("GdbStartupCommands"));
item->setDefaultValue(QString()); item->setDefaultValue(QString());
......
...@@ -124,6 +124,7 @@ enum DebuggerActionCode ...@@ -124,6 +124,7 @@ enum DebuggerActionCode
AutoEnrichParameters, AutoEnrichParameters,
UseDynamicType, UseDynamicType,
TargetAsync, TargetAsync,
WarnOnReleaseBuilds,
// Stack // Stack
MaximalStackDepth, MaximalStackDepth,
......
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
#include <projectexplorer/itaskhandler.h> #include <projectexplorer/itaskhandler.h>
#include <texteditor/itexteditor.h> #include <texteditor/itexteditor.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/elfreader.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
...@@ -2150,6 +2151,8 @@ void GdbEngine::setupEngine() ...@@ -2150,6 +2151,8 @@ void GdbEngine::setupEngine()
} }
QTC_CHECK(state() == EngineSetupRequested); QTC_CHECK(state() == EngineSetupRequested);
if (debuggerCore()->boolSetting(WarnOnReleaseBuilds))
checkForReleaseBuild();
m_gdbAdapter->startAdapter(); m_gdbAdapter->startAdapter();
} }
...@@ -5345,6 +5348,62 @@ bool GdbEngine::attemptQuickStart() const ...@@ -5345,6 +5348,62 @@ bool GdbEngine::attemptQuickStart() const
return true; return true;
} }
void GdbEngine::checkForReleaseBuild()
{
QString binary = startParameters().executable;
Utils::ElfReader reader(binary);
QList<QByteArray> names = reader.sectionNames();
QString error = reader.errorString();
showMessage(_("EXAMINING ") + binary);
QByteArray msg = "ELF SECTIONS: ";
static QList<QByteArray> interesting;
if (interesting.isEmpty()) {
interesting.append(".debug_info");
interesting.append(".debug_abbrev");
interesting.append(".debug_line");
interesting.append(".debug_str");
interesting.append(".debug_loc");
interesting.append(".debug_range");
interesting.append(".gdb_index");
interesting.append(".note.gnu.build-id");
interesting.append(".gnu.hash");
}
QSet<QByteArray> seen;
foreach (const QByteArray &name, names) {
msg.append(name);
msg.append(' ');
if (interesting.contains(name))
seen.insert(name);
}
showMessage(_(msg));
if (!error.isEmpty()) {
showMessage(_("ERROR WHILE READING ELF SECTIONS: ") + error);
return;
}
if (names.isEmpty()) {
showMessage(_("NO SECTION HEADERS FOUND"));
return;
}
if (names.contains(".debug_info"))
return;
QString warning;
warning = tr("This does not seem to be a \"Debug\" build.\n"
"Setting breakpoints by file name and line number may fail.\n");
foreach (const QByteArray &name, interesting) {
QString found = seen.contains(name) ? tr("Found.") : tr("Not Found.");
warning.append(tr("\nSection %1: %2").arg(_(name)).arg(found));
}
showMessageBox(QMessageBox::Information, tr("Warning"), warning);
}
// //
// Factory // Factory
// //
......
...@@ -403,6 +403,7 @@ private: ////////// Gdb Command Management ////////// ...@@ -403,6 +403,7 @@ private: ////////// Gdb Command Management //////////
QList<GdbCommand> m_commandsToRunOnTemporaryBreak; QList<GdbCommand> m_commandsToRunOnTemporaryBreak;
int gdbVersion() const { return m_gdbVersion; } int gdbVersion() const { return m_gdbVersion; }
void checkForReleaseBuild();
private: ////////// Gdb Output, State & Capability Handling ////////// private: ////////// Gdb Output, State & Capability Handling //////////
......
...@@ -66,6 +66,7 @@ public: ...@@ -66,6 +66,7 @@ public:
QCheckBox *checkBoxAdjustBreakpointLocations; QCheckBox *checkBoxAdjustBreakpointLocations;
QCheckBox *checkBoxUseDynamicType; QCheckBox *checkBoxUseDynamicType;
QCheckBox *checkBoxLoadGdbInit; QCheckBox *checkBoxLoadGdbInit;
QCheckBox *checkBoxWarnOnReleaseBuilds;
QLabel *labelDangerous; QLabel *labelDangerous;
QCheckBox *checkBoxTargetAsync; QCheckBox *checkBoxTargetAsync;
QCheckBox *checkBoxAutoEnrichParameters; QCheckBox *checkBoxAutoEnrichParameters;
...@@ -146,6 +147,13 @@ public: ...@@ -146,6 +147,13 @@ public:
"This allows or inhibits reading the user's default\n" "This allows or inhibits reading the user's default\n"
".gdbinit file on debugger startup.")); ".gdbinit file on debugger startup."));
checkBoxWarnOnReleaseBuilds = new QCheckBox(groupBoxGeneral);
checkBoxWarnOnReleaseBuilds->setText(GdbOptionsPage::tr(
"Warn when debugging \"Release\" builds"));
checkBoxWarnOnReleaseBuilds->setToolTip(GdbOptionsPage::tr(
"Show a warning when starting the debugger "
"on a binary with insufficient debug information."));
labelDangerous = new QLabel(GdbOptionsPage::tr( labelDangerous = new QLabel(GdbOptionsPage::tr(
"The options below should be used with care.")); "The options below should be used with care."));
...@@ -223,6 +231,7 @@ public: ...@@ -223,6 +231,7 @@ public:
formLayout->addRow(checkBoxAdjustBreakpointLocations); formLayout->addRow(checkBoxAdjustBreakpointLocations);
formLayout->addRow(checkBoxUseDynamicType); formLayout->addRow(checkBoxUseDynamicType);
formLayout->addRow(checkBoxLoadGdbInit); formLayout->addRow(checkBoxLoadGdbInit);
formLayout->addRow(checkBoxWarnOnReleaseBuilds);
formLayout->addRow(new QLabel(QString())); formLayout->addRow(new QLabel(QString()));
formLayout->addRow(labelDangerous); formLayout->addRow(labelDangerous);
formLayout->addRow(checkBoxTargetAsync); formLayout->addRow(checkBoxTargetAsync);
...@@ -282,6 +291,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent) ...@@ -282,6 +291,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
m_ui->checkBoxUseDynamicType); m_ui->checkBoxUseDynamicType);
m_group.insert(debuggerCore()->action(TargetAsync), m_group.insert(debuggerCore()->action(TargetAsync),
m_ui->checkBoxTargetAsync); m_ui->checkBoxTargetAsync);
m_group.insert(debuggerCore()->action(WarnOnReleaseBuilds),
m_ui->checkBoxWarnOnReleaseBuilds);
m_group.insert(debuggerCore()->action(AdjustBreakpointLocations), m_group.insert(debuggerCore()->action(AdjustBreakpointLocations),
m_ui->checkBoxAdjustBreakpointLocations); m_ui->checkBoxAdjustBreakpointLocations);
m_group.insert(debuggerCore()->action(BreakOnWarning), m_group.insert(debuggerCore()->action(BreakOnWarning),
...@@ -316,6 +327,7 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent) ...@@ -316,6 +327,7 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
<< sep << m_ui->groupBoxGeneral->title() << sep << m_ui->groupBoxGeneral->title()
<< sep << m_ui->checkBoxLoadGdbInit->text() << sep << m_ui->checkBoxLoadGdbInit->text()
<< sep << m_ui->checkBoxTargetAsync->text() << sep << m_ui->checkBoxTargetAsync->text()
<< sep << m_ui->checkBoxWarnOnReleaseBuilds->text()
<< sep << m_ui->checkBoxUseDynamicType->text() << sep << m_ui->checkBoxUseDynamicType->text()
<< sep << m_ui->labelGdbWatchdogTimeout->text() << sep << m_ui->labelGdbWatchdogTimeout->text()
<< sep << m_ui->checkBoxEnableReverseDebugging->text() << sep << m_ui->checkBoxEnableReverseDebugging->text()
......
...@@ -43,8 +43,6 @@ ...@@ -43,8 +43,6 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess>
#include <QMessageBox>
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
...@@ -100,7 +98,6 @@ void LocalPlainGdbAdapter::startAdapter() ...@@ -100,7 +98,6 @@ void LocalPlainGdbAdapter::startAdapter()
return; return;
} }
checkForReleaseBuild();
m_engine->handleAdapterStarted(); m_engine->handleAdapterStarted();
} }
...@@ -121,52 +118,6 @@ void LocalPlainGdbAdapter::shutdownAdapter() ...@@ -121,52 +118,6 @@ void LocalPlainGdbAdapter::shutdownAdapter()
m_engine->notifyAdapterShutdownOk(); m_engine->notifyAdapterShutdownOk();
} }
void LocalPlainGdbAdapter::checkForReleaseBuild()
{
#ifndef Q_OS_MAC
// There is usually no objdump on Mac, and if there is,
// there are no .debug_info sections.
QString objDump = _("objdump");
// Windows: Locate objdump in the debuggee's (MinGW) environment
if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS
&& startParameters().environment.size()) {
objDump = startParameters().environment.searchInPath(objDump);
} else {
objDump = Utils::Environment::systemEnvironment().searchInPath(objDump);
}
if (objDump.isEmpty()) {
showMessage(_("Could not locate objdump command for release build check"), LogWarning);
return;
}
// Quick check for a "release" build
QProcess proc;
QStringList args;
args.append(_("-h"));
args.append(_("-j"));
args.append(_(".debug_info"));
args.append(startParameters().executable);
proc.start(objDump, args);
proc.closeWriteChannel();
if (!proc.waitForStarted()) {
showMessage(_("OBJDUMP PROCESS COULD NOT BE STARTED. "
"RELEASE BUILD CHECK WILL FAIL"));
return;
}
proc.waitForFinished();
QByteArray ba = proc.readAllStandardOutput();
// This should yield something like
// "debuggertest: file format elf32-i386\n\n"
// "Sections:\nIdx Name Size VMA LMA File off Algn\n"
// "30 .debug_info 00087d36 00000000 00000000 0006bbd5 2**0\n"
// " CONTENTS, READONLY, DEBUGGING"
if (ba.contains("Sections:") && !ba.contains(".debug_info")) {
showMessageBox(QMessageBox::Information, tr("Warning"),
tr("This does not seem to be a \"Debug\" build.\n"
"Setting breakpoints by file name and line number may fail."));
}
#endif
}
void LocalPlainGdbAdapter::interruptInferior() void LocalPlainGdbAdapter::interruptInferior()
{ {
interruptLocalInferior(m_engine->inferiorPid()); interruptLocalInferior(m_engine->inferiorPid());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment