debugger: make use of full source file list optional

(cherry picked from commit 8c52f5720c)
This commit is contained in:
hjk
2009-12-09 11:13:20 +01:00
committed by con
parent 769c51504c
commit ca637fdc33
7 changed files with 78 additions and 22 deletions

View File

@@ -248,6 +248,14 @@ DebuggerSettings *DebuggerSettings::instance()
item->setText(tr("Synchronize breakpoints")); item->setText(tr("Synchronize breakpoints"));
instance->insertItem(SynchronizeBreakpoints, item); instance->insertItem(SynchronizeBreakpoints, item);
item = new SavedAction(instance);
item->setText(tr("Use precise breakpoints"));
item->setCheckable(true);
item->setDefaultValue(true);
item->setValue(true);
item->setSettingsKey(debugModeGroup, QLatin1String("UsePreciseBreakpoints"));
instance->insertItem(UsePreciseBreakpoints, item);
// //
// Settings // Settings
// //

View File

@@ -126,6 +126,7 @@ enum DebuggerActionCode
SelectedPluginBreakpoints, SelectedPluginBreakpoints,
NoPluginBreakpoints, NoPluginBreakpoints,
SelectedPluginBreakpointsPattern, SelectedPluginBreakpointsPattern,
UsePreciseBreakpoints
}; };
// singleton access // singleton access

View File

@@ -360,6 +360,7 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
m_group.insert(theDebuggerAction(MaximalStackDepth), m_group.insert(theDebuggerAction(MaximalStackDepth),
m_ui.spinBoxMaximalStackDepth); m_ui.spinBoxMaximalStackDepth);
m_group.insert(theDebuggerAction(LogTimeStamps), 0); m_group.insert(theDebuggerAction(LogTimeStamps), 0);
m_group.insert(theDebuggerAction(UsePreciseBreakpoints), 0);
#ifdef USE_REVERSE_DEBUGGING #ifdef USE_REVERSE_DEBUGGING
m_ui.checkBoxEnableReverseDebugging->hide(); m_ui.checkBoxEnableReverseDebugging->hide();

View File

@@ -271,8 +271,9 @@ void GdbEngine::initializeVariables()
m_shortToFullName.clear(); m_shortToFullName.clear();
m_varToType.clear(); m_varToType.clear();
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
m_sourcesListUpdating = false; m_sourcesListUpdating = false;
m_breakListUpdating = false;
m_oldestAcceptableToken = -1; m_oldestAcceptableToken = -1;
m_outputCodec = QTextCodec::codecForLocale(); m_outputCodec = QTextCodec::codecForLocale();
m_pendingRequests = 0; m_pendingRequests = 0;
@@ -439,14 +440,14 @@ void GdbEngine::handleResponse(const QByteArray &buff)
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))); showStatusMessage(tr("Library %1 loaded.").arg(_(id)));
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
} 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",
// host-name="/usr/lib/libdrm.so.2" // host-name="/usr/lib/libdrm.so.2"
QByteArray id = result.findChild("id").data(); QByteArray id = result.findChild("id").data();
showStatusMessage(tr("Library %1 unloaded.").arg(_(id))); showStatusMessage(tr("Library %1 unloaded.").arg(_(id)));
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
} else if (asyncClass == "thread-group-created") { } else if (asyncClass == "thread-group-created") {
// Archer has "{id="28902"}" // Archer has "{id="28902"}"
QByteArray id = result.findChild("id").data(); QByteArray id = result.findChild("id").data();
@@ -475,7 +476,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
} else if (asyncClass == "shlibs-updated") { } else if (asyncClass == "shlibs-updated") {
// MAC announces updated libs // MAC announces updated libs
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
} else if (asyncClass == "shlibs-added") { } else if (asyncClass == "shlibs-added") {
// MAC announces added libs // MAC announces added libs
// {shlib-info={num="2", name="libmathCommon.A_debug.dylib", // {shlib-info={num="2", name="libmathCommon.A_debug.dylib",
@@ -483,7 +484,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// state="Y", path="/usr/lib/system/libmathCommon.A_debug.dylib", // state="Y", path="/usr/lib/system/libmathCommon.A_debug.dylib",
// description="/usr/lib/system/libmathCommon.A_debug.dylib", // description="/usr/lib/system/libmathCommon.A_debug.dylib",
// loaded_addr="0x7f000", slide="0x7f000", prefix=""}} // loaded_addr="0x7f000", slide="0x7f000", prefix=""}}
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
#endif #endif
} else { } else {
qDebug() << "IGNORED ASYNC OUTPUT" qDebug() << "IGNORED ASYNC OUTPUT"
@@ -517,7 +518,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// Show some messages to give the impression something happens. // Show some messages to give the impression something happens.
if (data.startsWith("Reading symbols from ")) { if (data.startsWith("Reading symbols from ")) {
showStatusMessage(tr("Reading %1...").arg(_(data.mid(21))), 1000); showStatusMessage(tr("Reading %1...").arg(_(data.mid(21))), 1000);
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
} else if (data.startsWith("[New ") || data.startsWith("[Thread ")) { } else if (data.startsWith("[New ") || data.startsWith("[Thread ")) {
if (data.endsWith('\n')) if (data.endsWith('\n'))
data.chop(1); data.chop(1);
@@ -988,6 +989,8 @@ void GdbEngine::updateAll()
void GdbEngine::handleQuerySources(const GdbResponse &response) void GdbEngine::handleQuerySources(const GdbResponse &response)
{ {
m_sourcesListUpdating = false;
m_sourcesListOutdated = false;
if (response.resultClass == GdbResultDone) { if (response.resultClass == GdbResultDone) {
QMap<QString, QString> oldShortToFull = m_shortToFullName; QMap<QString, QString> oldShortToFull = m_shortToFullName;
m_shortToFullName.clear(); m_shortToFullName.clear();
@@ -1161,7 +1164,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
// on Windows it simply forgets about it. Thus, we identify the response // on Windows it simply forgets about it. Thus, we identify the response
// based on it having no frame information. // based on it having no frame information.
if (!data.findChild("frame").isValid()) { if (!data.findChild("frame").isValid()) {
m_modulesListOutdated = m_sourcesListOutdated = true; invalidateSourcesList();
// Each stop causes a roundtrip and button flicker, so prevent // Each stop causes a roundtrip and button flicker, so prevent
// a flood of useless stops. Will be automatically re-enabled. // a flood of useless stops. Will be automatically re-enabled.
postCommand(_("set stop-on-solib-events 0")); postCommand(_("set stop-on-solib-events 0"));
@@ -1273,14 +1276,17 @@ void GdbEngine::handleStop1(const GdbMi &data)
{ {
if (m_modulesListOutdated) if (m_modulesListOutdated)
reloadModulesInternal(); // This is for display only reloadModulesInternal(); // This is for display only
if (m_sourcesListOutdated) if (m_sourcesListOutdated && theDebuggerBoolSetting(UsePreciseBreakpoints))
reloadSourceFilesInternal(); // This needs to be done before fullName() may need it reloadSourceFilesInternal(); // This needs to be done before fullName() may need it
// Older gdb versions do not produce "library loaded" messages if (m_breakListOutdated)
// so the breakpoint update is not triggered. reloadBreakListInternal();
if (m_gdbVersion < 70000 && !m_isMacGdb && !m_sourcesListUpdating else
&& manager()->breakHandler()->size() > 0) // Older gdb versions do not produce "library loaded" messages
postCommand(_("-break-list"), CB(handleBreakList)); // so the breakpoint update is not triggered.
if (m_gdbVersion < 70000 && !m_isMacGdb && !m_breakListUpdating
&& manager()->breakHandler()->size() > 0)
reloadBreakListInternal();
QByteArray reason = data.findChild("reason").data(); QByteArray reason = data.findChild("reason").data();
if (reason == "breakpoint-hit") { if (reason == "breakpoint-hit") {
@@ -1876,8 +1882,8 @@ void GdbEngine::breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt
QString GdbEngine::breakLocation(const QString &file) const QString GdbEngine::breakLocation(const QString &file) const
{ {
QTC_ASSERT(!m_sourcesListOutdated, /* */) QTC_ASSERT(!m_breakListOutdated, /* */)
QTC_ASSERT(!m_sourcesListUpdating, /* */) QTC_ASSERT(!m_breakListUpdating, /* */)
QString where = m_fullToShortName.value(file); QString where = m_fullToShortName.value(file);
if (where.isEmpty()) if (where.isEmpty())
return QFileInfo(file).fileName(); return QFileInfo(file).fileName();
@@ -1912,10 +1918,14 @@ void GdbEngine::sendInsertBreakpoint(int index)
postCommand(cmd, NeedsStop, CB(handleBreakInsert), index); postCommand(cmd, NeedsStop, CB(handleBreakInsert), index);
} }
void GdbEngine::reloadBreakListInternal()
{
m_breakListUpdating = true;
postCommand(_("-break-list"), CB(handleBreakList));
}
void GdbEngine::handleBreakList(const GdbResponse &response) void GdbEngine::handleBreakList(const GdbResponse &response)
{ {
m_sourcesListUpdating = false;
// 45^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[ // 45^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[
// {width="3",alignment="-1",col_name="number",colhdr="Num"}, ... // {width="3",alignment="-1",col_name="number",colhdr="Num"}, ...
// body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", // body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",
@@ -1962,6 +1972,8 @@ void GdbEngine::handleBreakList(const GdbMi &table)
//qDebug() << "CANNOT HANDLE RESPONSE" << bkpts.at(index).toString(); //qDebug() << "CANNOT HANDLE RESPONSE" << bkpts.at(index).toString();
} }
m_breakListUpdating = false;
m_breakListOutdated = false;
attemptBreakpointSynchronization(); attemptBreakpointSynchronization();
} }
@@ -2118,6 +2130,11 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response)
void GdbEngine::attemptBreakpointSynchronization() void GdbEngine::attemptBreakpointSynchronization()
{ {
//QTC_ASSERT(!m_breakListUpdating,
// qDebug() << "BREAK LIST CURRENTLY UPDATING"; return);
QTC_ASSERT(!m_sourcesListUpdating,
qDebug() << "SOURCES LIST CURRENTLY UPDATING"; return);
switch (state()) { switch (state()) {
case InferiorStarting: case InferiorStarting:
case InferiorRunningRequested: case InferiorRunningRequested:
@@ -2132,10 +2149,13 @@ void GdbEngine::attemptBreakpointSynchronization()
// For best results, we rely on an up-to-date fullname mapping. // For best results, we rely on an up-to-date fullname mapping.
// The listing completion will retrigger us, so no futher action is needed. // The listing completion will retrigger us, so no futher action is needed.
if (m_sourcesListOutdated) { if (m_sourcesListOutdated && theDebuggerBoolSetting(UsePreciseBreakpoints)) {
reloadSourceFilesInternal(); reloadSourceFilesInternal();
reloadBreakListInternal();
return; return;
} else if (m_sourcesListUpdating) { }
if (m_breakListOutdated) {
reloadBreakListInternal();
return; return;
} }
@@ -2318,6 +2338,13 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
void GdbEngine::invalidateSourcesList()
{
m_modulesListOutdated = true;
m_sourcesListOutdated = true;
m_breakListOutdated = true;
}
void GdbEngine::reloadSourceFiles() void GdbEngine::reloadSourceFiles()
{ {
if ((state() == InferiorRunning || state() == InferiorStopped) if ((state() == InferiorRunning || state() == InferiorStopped)
@@ -2327,10 +2354,9 @@ void GdbEngine::reloadSourceFiles()
void GdbEngine::reloadSourceFilesInternal() void GdbEngine::reloadSourceFilesInternal()
{ {
QTC_ASSERT(!m_sourcesListUpdating, /**/);
m_sourcesListUpdating = true; m_sourcesListUpdating = true;
m_sourcesListOutdated = false;
postCommand(_("-file-list-exec-source-files"), NeedsStop, CB(handleQuerySources)); postCommand(_("-file-list-exec-source-files"), NeedsStop, CB(handleQuerySources));
postCommand(_("-break-list"), CB(handleBreakList));
#if 0 #if 0
if (m_gdbVersion < 70000 && !m_isMacGdb) if (m_gdbVersion < 70000 && !m_isMacGdb)
postCommand(_("set stop-on-solib-events 1")); postCommand(_("set stop-on-solib-events 1"));
@@ -4192,7 +4218,8 @@ QString GdbEngine::parseDisassembler(const GdbMi &lines)
// mixed mode // mixed mode
if (!fileLoaded) { if (!fileLoaded) {
QString fileName = QFile::decodeName(child.findChild("file").data()); QString fileName = QFile::decodeName(child.findChild("file").data());
QFile file(fullName(fileName)); fileName = cleanupFullName(fileName);
QFile file(fileName);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
fileContents = file.readAll().split('\n'); fileContents = file.readAll().split('\n');
fileLoaded = true; fileLoaded = true;

View File

@@ -328,6 +328,7 @@ private: ////////// View & Data Stuff //////////
void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt); void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
void sendInsertBreakpoint(int index); void sendInsertBreakpoint(int index);
QString breakLocation(const QString &file) const; QString breakLocation(const QString &file) const;
void reloadBreakListInternal();
// //
// Modules specific stuff // Modules specific stuff
@@ -379,8 +380,11 @@ private: ////////// View & Data Stuff //////////
QMap<QString, QString> m_shortToFullName; QMap<QString, QString> m_shortToFullName;
QMap<QString, QString> m_fullToShortName; QMap<QString, QString> m_fullToShortName;
void invalidateSourcesList();
bool m_sourcesListOutdated; bool m_sourcesListOutdated;
bool m_sourcesListUpdating; bool m_sourcesListUpdating;
bool m_breakListOutdated;
bool m_breakListUpdating;
// //
// Stack specific stuff // Stack specific stuff

View File

@@ -50,6 +50,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
m_ui.scriptFileChooser); m_ui.scriptFileChooser);
m_group.insert(theDebuggerAction(GdbEnvironment), m_group.insert(theDebuggerAction(GdbEnvironment),
m_ui.environmentEdit); m_ui.environmentEdit);
m_group.insert(theDebuggerAction(UsePreciseBreakpoints),
m_ui.checkBoxUsePreciseBreakpoints);
#if 1 #if 1
m_ui.groupBoxPluginDebugging->hide(); m_ui.groupBoxPluginDebugging->hide();

View File

@@ -62,6 +62,19 @@
<item row="0" column="1"> <item row="0" column="1">
<widget class="Utils::PathChooser" name="gdbLocationChooser" native="true"/> <widget class="Utils::PathChooser" name="gdbLocationChooser" native="true"/>
</item> </item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkBoxUsePreciseBreakpoints">
<property name="text">
<string>Use full path information to set breakpoints</string>
</property>
<property name="toolTip">
<string>When this option is checked, the debugger plugin attempts
to extract full path information for all source files from gdb. This is a
slow process but enables setting breakpoints in files with the same file
name in different directories.</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>