forked from qt-creator/qt-creator
Debugger: Move initial GDB breakpoint settings after target setup
While GDB can handle breakpoints set before specifying an executable fine, it stresses the machinery unnecessarily and fails in corner cases ("wrong" dynamic loader etc). We can avoid most of that by moving the breakpoint setting to a later point in the process. Change-Id: I0450a0e43a81c80bfdfefb7b67f6799042e0ec26 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -3855,33 +3855,16 @@ void GdbEngine::prepareForRestart()
|
|||||||
|
|
||||||
void GdbEngine::handleInferiorPrepared()
|
void GdbEngine::handleInferiorPrepared()
|
||||||
{
|
{
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
|
||||||
|
|
||||||
CHECK_STATE(EngineSetupRequested);
|
CHECK_STATE(EngineSetupRequested);
|
||||||
|
|
||||||
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
if (!rp.commandsAfterConnect.isEmpty()) {
|
if (!rp.commandsAfterConnect.isEmpty()) {
|
||||||
const QString commands = expand(rp.commandsAfterConnect);
|
const QString commands = expand(rp.commandsAfterConnect);
|
||||||
for (const QString &command : commands.split('\n'))
|
for (const QString &command : commands.split('\n'))
|
||||||
runCommand({command, NativeCommand});
|
runCommand({command, NativeCommand});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runParameters().startMode != AttachCore) { // No breakpoints in core files.
|
claimInitialBreakpoints();
|
||||||
const bool onAbort = boolSetting(BreakOnAbort);
|
|
||||||
const bool onWarning = boolSetting(BreakOnWarning);
|
|
||||||
const bool onFatal = boolSetting(BreakOnFatal);
|
|
||||||
if (onAbort || onWarning || onFatal) {
|
|
||||||
DebuggerCommand cmd("createSpecialBreakpoints");
|
|
||||||
cmd.arg("breakonabort", onAbort);
|
|
||||||
cmd.arg("breakonwarning", onWarning);
|
|
||||||
cmd.arg("breakonfatal", onFatal);
|
|
||||||
runCommand(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is ok to cut corners here and not wait for createSpecialBreakpoints()'s
|
|
||||||
// response, as the command is synchronous from Creator's point of view,
|
|
||||||
// and even if it fails (e.g. due to stripped binaries), continuing with
|
|
||||||
// the start up is the best we can do.
|
|
||||||
notifyEngineSetupOk();
|
notifyEngineSetupOk();
|
||||||
runEngine();
|
runEngine();
|
||||||
}
|
}
|
||||||
@@ -4039,6 +4022,34 @@ bool GdbEngine::isTermEngine() const
|
|||||||
return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && terminal();
|
return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && terminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbEngine::claimInitialBreakpoints()
|
||||||
|
{
|
||||||
|
CHECK_STATE(EngineSetupRequested);
|
||||||
|
|
||||||
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
|
if (rp.startMode != AttachCore) {
|
||||||
|
showStatusMessage(tr("Setting breakpoints..."));
|
||||||
|
showMessage(tr("Setting breakpoints..."));
|
||||||
|
BreakpointManager::claimBreakpointsForEngine(this);
|
||||||
|
|
||||||
|
const bool onAbort = boolSetting(BreakOnAbort);
|
||||||
|
const bool onWarning = boolSetting(BreakOnWarning);
|
||||||
|
const bool onFatal = boolSetting(BreakOnFatal);
|
||||||
|
if (onAbort || onWarning || onFatal) {
|
||||||
|
DebuggerCommand cmd("createSpecialBreakpoints");
|
||||||
|
cmd.arg("breakonabort", onAbort);
|
||||||
|
cmd.arg("breakonwarning", onWarning);
|
||||||
|
cmd.arg("breakonfatal", onFatal);
|
||||||
|
runCommand(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is ok to cut corners here and not wait for createSpecialBreakpoints()'s
|
||||||
|
// response, as the command is synchronous from Creator's point of view,
|
||||||
|
// and even if it fails (e.g. due to stripped binaries), continuing with
|
||||||
|
// the start up is the best we can do.
|
||||||
|
}
|
||||||
|
|
||||||
void GdbEngine::setupInferior()
|
void GdbEngine::setupInferior()
|
||||||
{
|
{
|
||||||
CHECK_STATE(EngineSetupRequested);
|
CHECK_STATE(EngineSetupRequested);
|
||||||
@@ -4049,13 +4060,6 @@ void GdbEngine::setupInferior()
|
|||||||
if (rp.breakOnMain)
|
if (rp.breakOnMain)
|
||||||
runCommand({"tbreak " + mainFunction()});
|
runCommand({"tbreak " + mainFunction()});
|
||||||
|
|
||||||
// Initial attempt to set breakpoints.
|
|
||||||
if (rp.startMode != AttachCore) {
|
|
||||||
showStatusMessage(tr("Setting breakpoints..."));
|
|
||||||
showMessage(tr("Setting breakpoints..."));
|
|
||||||
BreakpointManager::claimBreakpointsForEngine(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rp.startMode == AttachToRemoteProcess) {
|
if (rp.startMode == AttachToRemoteProcess) {
|
||||||
|
|
||||||
handleInferiorPrepared();
|
handleInferiorPrepared();
|
||||||
|
@@ -418,6 +418,7 @@ private: ////////// General Interface //////////
|
|||||||
|
|
||||||
QString mainFunction() const;
|
QString mainFunction() const;
|
||||||
void setupInferior();
|
void setupInferior();
|
||||||
|
void claimInitialBreakpoints();
|
||||||
|
|
||||||
Utils::QtcProcess m_gdbProc;
|
Utils::QtcProcess m_gdbProc;
|
||||||
OutputCollector m_outputCollector;
|
OutputCollector m_outputCollector;
|
||||||
|
Reference in New Issue
Block a user