From 13c9b42a216f56c33da57f54ecdae5797271407e Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 5 Jan 2021 17:56:46 +0100 Subject: [PATCH] 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 --- src/plugins/debugger/gdb/gdbengine.cpp | 56 ++++++++++++++------------ src/plugins/debugger/gdb/gdbengine.h | 1 + 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 69120534f12..a083185e5a9 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3855,33 +3855,16 @@ void GdbEngine::prepareForRestart() void GdbEngine::handleInferiorPrepared() { - const DebuggerRunParameters &rp = runParameters(); - CHECK_STATE(EngineSetupRequested); + const DebuggerRunParameters &rp = runParameters(); if (!rp.commandsAfterConnect.isEmpty()) { const QString commands = expand(rp.commandsAfterConnect); for (const QString &command : commands.split('\n')) runCommand({command, NativeCommand}); } - if (runParameters().startMode != AttachCore) { // No breakpoints in core files. - 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. + claimInitialBreakpoints(); notifyEngineSetupOk(); runEngine(); } @@ -4039,6 +4022,34 @@ bool GdbEngine::isTermEngine() const 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() { CHECK_STATE(EngineSetupRequested); @@ -4049,13 +4060,6 @@ void GdbEngine::setupInferior() if (rp.breakOnMain) 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) { handleInferiorPrepared(); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 31c076f5f1c..0387e9a31a6 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -418,6 +418,7 @@ private: ////////// General Interface ////////// QString mainFunction() const; void setupInferior(); + void claimInitialBreakpoints(); Utils::QtcProcess m_gdbProc; OutputCollector m_outputCollector;