Commit b439999f authored by hjk's avatar hjk Committed by Aurindam Jana
Browse files

debugger: try quicker start when no breakpoints are set



This prevents initial reading of debug information when no
breakpoints are set. The debug information will be read on
first stop instead, e.g. when the user interrupts.

Change-Id: I6156347bf108e9ed89f54ca67021f37c02fa5116
Reviewed-by: default avatarAurindam Jana <aurindam.jana@nokia.com>
parent 8209b9d9
......@@ -415,6 +415,12 @@ DebuggerSettings::DebuggerSettings(QSettings *settings)
item->setDefaultValue(false);
insertItem(AutoQuit, item);
item = new SavedAction(this);
item->setSettingsKey(debugModeGroup, QLatin1String("AttemptQuickStart"));
item->setCheckable(true);
item->setDefaultValue(false);
insertItem(AttemptQuickStart, item);
item = new SavedAction(this);
item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTips"));
item->setText(tr("Use tooltips in main editor when debugging"));
......
......@@ -118,6 +118,7 @@ enum DebuggerActionCode
// Gdb
LoadGdbInit,
AttemptQuickStart,
GdbStartupCommands,
GdbWatchdogTimeout,
AutoEnrichParameters,
......
......@@ -86,7 +86,7 @@ void AttachGdbAdapter::runEngine()
.arg(m_engine->inferiorPid()));
m_engine->notifyEngineRunAndInferiorStopOk();
GdbMi data;
m_engine->handleStop0(data);
m_engine->handleStop1(data);
}
void AttachGdbAdapter::handleAttach(const GdbResponse &response)
......
......@@ -262,6 +262,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
m_preparedForQmlBreak = false;
m_disassembleUsesComma = false;
m_actingOnExpectedStop = false;
m_fullStartDone = false;
invalidateSourcesList();
......@@ -1290,7 +1291,7 @@ void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response)
// This happens on old gdb. Trigger the effect of a '*stopped'.
showStatusMessage(tr("Jumped. Stopped"));
notifyInferiorSpontaneousStop();
handleStop1(response);
handleStop2(response);
}
}
......@@ -1388,6 +1389,15 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
return;
}
bool gotoHandleStop1 = true;
if (!m_fullStartDone) {
m_fullStartDone = true;
postCommand("sharedlibrary .*");
loadPythonDumpers();
postCommand("p 3", CB(handleStop1));
gotoHandleStop1 = false;
}
BreakpointResponseId rid(data.findChild("bkptno").data());
const GdbMi frame = data.findChild("frame");
......@@ -1467,7 +1477,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (isQmlStepBreakpoint1(rid))
return;
handleStop0(data);
if (gotoHandleStop1)
handleStop1(data);
}
static QByteArray stopSignal(Abi abi)
......@@ -1475,37 +1486,13 @@ static QByteArray stopSignal(Abi abi)
return (abi.os() == Abi::WindowsOS) ? QByteArray("SIGTRAP") : QByteArray("SIGINT");
}
void GdbEngine::handleStop0(const GdbMi &data)
{
#if 0 // See http://vladimir_prus.blogspot.com/2007/12/debugger-stories-pending-breakpoints.html
// Due to LD_PRELOADing the dumpers, these events can occur even before
// reaching the entry point. So handle it before the entry point hacks below.
if (reason.isEmpty() && m_gdbVersion < 70000 && !m_isMacGdb) {
// On Linux it reports "Stopped due to shared library event\n", but
// on Windows it simply forgets about it. Thus, we identify the response
// based on it having no frame information.
if (!data.findChild("frame").isValid()) {
invalidateSourcesList();
// Each stop causes a roundtrip and button flicker, so prevent
// a flood of useless stops. Will be automatically re-enabled.
postCommand("set stop-on-solib-events 0");
#if 0
// The related code (handleAqcuiredInferior()) is disabled as well.
if (debuggerCore()->boolSetting(SelectedPluginBreakpoints)) {
QString dataStr = _(data.toString());
showMessage(_("SHARED LIBRARY EVENT: ") + dataStr);
QString pat = theDebuggerStringSetting(SelectedPluginBreakpointsPattern);
showMessage(_("PATTERN: ") + pat);
postCommand("sharedlibrary " + pat.toLocal8Bit());
showStatusMessage(tr("Loading %1...").arg(dataStr));
}
#endif
continueInferiorInternal();
return;
}
}
#endif
void GdbEngine::handleStop1(const GdbResponse &response)
{
handleStop1(response.cookie.value<GdbMi>());
}
void GdbEngine::handleStop1(const GdbMi &data)
{
const GdbMi frame = data.findChild("frame");
const QByteArray reason = data.findChild("reason").data();
......@@ -1580,20 +1567,20 @@ void GdbEngine::handleStop0(const GdbMi &data)
if (initHelpers) {
tryLoadDebuggingHelpersClassic();
QVariant var = QVariant::fromValue<GdbMi>(data);
postCommand("p 4", CB(handleStop1), var); // dummy
postCommand("p 4", CB(handleStop2), var); // dummy
} else {
handleStop1(data);
handleStop2(data);
}
// Dumper loading is sequenced, as otherwise the display functions
// will start requesting data without knowing that dumpers are available.
}
void GdbEngine::handleStop1(const GdbResponse &response)
void GdbEngine::handleStop2(const GdbResponse &response)
{
handleStop1(response.cookie.value<GdbMi>());
handleStop2(response.cookie.value<GdbMi>());
}
void GdbEngine::handleStop1(const GdbMi &data)
void GdbEngine::handleStop2(const GdbMi &data)
{
if (isDying()) {
qDebug() << "HANDLING STOP WHILE DYING";
......@@ -2592,7 +2579,7 @@ QByteArray GdbEngine::breakpointLocation(BreakpointModelId id)
return (abi.os() == Abi::WindowsOS) ? "qMain" : "main";
}
if (data.type == BreakpointByFunction)
return data.functionName.toUtf8();
return '"' + data.functionName.toUtf8() + '"';
if (data.type == BreakpointByAddress)
return addressSpec(data.address);
......@@ -4814,7 +4801,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint)
showMessage(_("GDB STARTED, INITIALIZING IT"));
postCommand("show version", CB(handleShowVersion));
postCommand("-list-features", CB(handleListFeatures));
//postCommand("-list-features", CB(handleListFeatures));
//postCommand("-enable-timings");
//postCommand("set print static-members off"); // Seemingly doesn't work.
......@@ -4837,6 +4824,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint)
postCommand("set breakpoint pending on");
postCommand("set print elements 10000");
// Produces a few messages during symtab loading
//postCommand("set verbose on");
......@@ -4873,7 +4861,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint)
// displaced-stepping does not work in Thumb mode.
//postCommand("set displaced-stepping on");
postCommand("set trust-readonly-sections on", ConsoleCommand);
postCommand("set auto-solib-add on", ConsoleCommand);
postCommand("set remotecache on", ConsoleCommand);
//postCommand("set non-stop on", ConsoleCommand);
......@@ -4889,7 +4877,13 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint)
postCommand(cmd);
}
loadPythonDumpers();
if (attemptQuickStart()) {
postCommand("set auto-solib-add off", ConsoleCommand);
} else {
m_fullStartDone = true;
postCommand("set auto-solib-add on", ConsoleCommand);
loadPythonDumpers();
}
return true;
}
......@@ -4929,8 +4923,7 @@ void GdbEngine::loadPythonDumpers()
loadInitScript();
postCommand("bbsetup",
ConsoleCommand, CB(handleHasPython));
postCommand("bbsetup", ConsoleCommand, CB(handleHasPython));
}
void GdbEngine::handleGdbError(QProcess::ProcessError error)
......@@ -5321,6 +5314,22 @@ void GdbEngine::requestDebugInformation(const DebugInfoTask &task)
QProcess::startDetached(task.command);
}
bool GdbEngine::attemptQuickStart() const
{
// Don't try if the user does not ask for it.
if (!debuggerCore()->boolSetting(AttemptQuickStart))
return false;
// Don't try if there are breakpoints we might be able to handle.
BreakHandler *handler = breakHandler();
foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
if (acceptsBreakpoint(id))
return false;
}
return true;
}
//
// Factory
//
......
......@@ -420,9 +420,10 @@ private: ////////// Gdb Output, State & Capability Handling //////////
Q_SLOT void handleResponse(const QByteArray &buff);
void handleStopResponse(const GdbMi &data);
void handleResultRecord(GdbResponse *response);
void handleStop0(const GdbMi &data);
void handleStop1(const GdbResponse &response);
void handleStop1(const GdbMi &data);
void handleStop2(const GdbResponse &response);
void handleStop2(const GdbMi &data);
Q_SLOT void handleStop2();
StackFrame parseStackFrame(const GdbMi &mi, int level);
void resetCommandQueue();
......@@ -746,6 +747,11 @@ private: ////////// View & Data Stuff //////////
friend class DebugInfoTaskHandler;
void requestDebugInformation(const DebugInfoTask &task);
DebugInfoTaskHandler *m_debugInfoTaskHandler;
// Indicates whether we had at least one full attempt to load
// debug information.
bool attemptQuickStart() const;
bool m_fullStartDone;
};
} // namespace Internal
......
......@@ -73,6 +73,7 @@ public:
QCheckBox *checkBoxBreakOnFatal;
QCheckBox *checkBoxBreakOnRaise;
QCheckBox *checkBoxEnableReverseDebugging;
QCheckBox *checkBoxAttemptQuickStart;
QGroupBox *groupBoxStartupCommands;
QTextEdit *textEditStartupCommands;
......@@ -176,6 +177,13 @@ public:
"It exhibits unpredictable behavior when going backwards over system "
"calls and is very likely to destroy your debugging session.</p><body></html>"));
checkBoxAttemptQuickStart = new QCheckBox(groupBoxGeneral);
checkBoxAttemptQuickStart->setText(GdbOptionsPage::tr("Attempt quick start"));
checkBoxAttemptQuickStart->setToolTip(GdbOptionsPage::tr("Checking this option "
"will postpone reading debug information as long as possible. This can result "
"in faster startup times at the price of not being able to set breakpoints "
"by file and number."));
groupBoxStartupCommands = new QGroupBox(q);
groupBoxStartupCommands->setTitle(GdbOptionsPage::tr("Additional Startup Commands"));
......@@ -223,6 +231,7 @@ public:
formLayout->addRow(checkBoxBreakOnFatal);
formLayout->addRow(checkBoxBreakOnRaise);
formLayout->addRow(checkBoxEnableReverseDebugging);
formLayout->addRow(checkBoxAttemptQuickStart);
QGridLayout *startLayout = new QGridLayout(groupBoxStartupCommands);
startLayout->addWidget(textEditStartupCommands, 0, 0, 1, 1);
......@@ -302,6 +311,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
m_ui->checkBoxBreakOnRaise);
m_group.insert(debuggerCore()->action(GdbWatchdogTimeout),
m_ui->spinBoxGdbWatchdogTimeout);
m_group.insert(debuggerCore()->action(AttemptQuickStart),
m_ui->checkBoxAttemptQuickStart);
m_group.insert(debuggerCore()->action(UseMessageBoxForSignals),
m_ui->checkBoxUseMessageBoxForSignals);
......@@ -330,6 +341,7 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
<< sep << m_ui->checkBoxSkipKnownFrames->text()
<< sep << m_ui->checkBoxUseMessageBoxForSignals->text()
<< sep << m_ui->checkBoxAdjustBreakpointLocations->text()
<< sep << m_ui->checkBoxAttemptQuickStart->text()
// << sep << m_ui->groupBoxPluginDebugging->title()
// << sep << m_ui->radioButtonAllPluginBreakpoints->text()
// << sep << m_ui->radioButtonSelectedPluginBreakpoints->text()
......
......@@ -2048,7 +2048,7 @@ namespace final {
// Continue.
// Jump over next line.
return;
//return;
while (a > 0)
++a;
dummyStatement(&a);
......
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