{
switch (sm) {
case NoStartMode:
- case AttachCore:
case StartRemoteGdb:
return false;
default:
#endif
}
-static inline QString msgNoCdbBinaryForToolChain(const ProjectExplorer::Abi &tc)
+static inline QString msgNoCdbBinaryForToolChain(const Abi &tc)
{
return CdbEngine::tr("There is no CDB binary available for binaries in format '%1'").arg(tc.toString());
}
+static inline bool isMsvcFlavor(Abi::OSFlavor osf)
+{
+ return osf == Abi::WindowsMsvc2005Flavor
+ || osf == Abi::WindowsMsvc2008Flavor
+ || osf == Abi::WindowsMsvc2010Flavor;
+}
+
static QString cdbBinary(const DebuggerStartParameters &sp)
{
if (!sp.debuggerCommand.isEmpty()) {
// Do not use a GDB binary if we got started for a project with MinGW runtime.
- const bool abiMatch = sp.toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS
- && (sp.toolChainAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor
- || sp.toolChainAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor
- || sp.toolChainAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor);
+ const bool abiMatch = sp.toolChainAbi.os() == Abi::WindowsOS
+ && isMsvcFlavor(sp.toolChainAbi.osFlavor());
if (abiMatch)
return sp.debuggerCommand;
}
return false;
}
+ if (sp.startMode == AttachCore && !isMsvcFlavor(sp.toolChainAbi.osFlavor())) {
+ check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine cannot debug gdb core files."));
+ return false;
+ }
+
if (cdbBinary(sp).isEmpty()) {
check->errorDetails.push_back(msgNoCdbBinaryForToolChain(sp.toolChainAbi));
- check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY);
- check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY);
+ check->settingsCategory = QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
+ check->settingsPage = QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
return false;
}
CdbEngine::CdbEngine(const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine, const OptionsPtr &options) :
- DebuggerEngine(sp, masterEngine),
+ DebuggerEngine(sp, CppLanguage, masterEngine),
m_creatorExtPrefix("<qtcreatorcdbext>|"),
m_tokenPrefix("<token>"),
m_options(options),
m_pendingBreakpointMap.clear();
m_customSpecialStopData.clear();
m_symbolAddressCache.clear();
+ m_coreStopReason.reset();
// Create local list of mappings in native separators
m_sourcePathMappings.clear();
const QString extensionFileName = extensionFi.fileName();
// Prepare arguments
QStringList arguments;
- const bool isRemote = sp.startMode == AttachToRemote;
+ const bool isRemote = sp.startMode == AttachToRemoteServer;
if (isRemote) { // Must be first
arguments << QLatin1String("-remote") << sp.remoteChannel;
} else {
nativeArguments.push_back(blank);
nativeArguments += QDir::toNativeSeparators(sp.executable);
break;
- case AttachToRemote:
+ case AttachToRemoteServer:
break;
case AttachExternal:
case AttachCrashedExternal:
arguments << QLatin1String("-pr") << QLatin1String("-pb");
}
break;
+ case AttachCore:
+ arguments << QLatin1String("-z") << sp.coreFile;
+ break;
default:
*errorMessage = QString::fromLatin1("Internal error: Unsupported start mode %1.").arg(sp.startMode);
return false;
{
if (debug)
qDebug("setupInferior");
+ // QmlCppEngine expects the QML engine to be connected before any breakpoints are hit
+ // (attemptBreakpointSynchronization() will be directly called then)
attemptBreakpointSynchronization();
-
if (startParameters().breakOnMain) {
const BreakpointParameters bp(BreakpointAtMain);
postCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings,
qDebug("runEngine");
foreach (const QString &breakEvent, m_options->breakEvents)
postCommand(QByteArray("sxe ") + breakEvent.toAscii(), 0);
- postCommand("g", 0);
+ if (startParameters().startMode == AttachCore) {
+ QTC_ASSERT(!m_coreStopReason.isNull(), return; );
+ notifyInferiorUnrunnable();
+ processStop(*m_coreStopReason, false);
+ } else {
+ postCommand("g", 0);
+ }
}
bool CdbEngine::commandsPending() const
if (startParameters().startMode == AttachExternal || startParameters().startMode == AttachCrashedExternal)
detachDebugger();
// Remote requires a bit more force to quit.
- if (m_effectiveStartMode == AttachToRemote) {
+ if (m_effectiveStartMode == AttachToRemoteServer) {
postCommand(m_extensionCommandPrefixBA + "shutdownex", 0);
postCommand("qq", 0);
} else {
unsigned CdbEngine::debuggerCapabilities() const
{
return DisassemblerCapability | RegisterCapability | ShowMemoryCapability
- |WatchpointByAddressCapability|JumpToLineCapability|AddWatcherCapability
+ |WatchpointByAddressCapability|JumpToLineCapability|AddWatcherCapability|WatchWidgetsCapability
|ReloadModuleCapability
|BreakOnThrowAndCatchCapability // Sort-of: Can break on throw().
|BreakConditionCapability|TracePointCapability
bool CdbEngine::canInterruptInferior() const
{
- return m_effectiveStartMode != AttachToRemote && inferiorPid();
+ return m_effectiveStartMode != AttachToRemoteServer && inferiorPid();
}
void CdbEngine::interruptInferior()
for (int i = 0; i < size; i++) {
if (addresses.at(i) <= needle) {
const quint64 offset = needle - addresses.at(i);
- if (offset < offset) {
+ if (offset < closestOffset) {
closestOffset = offset;
closestIndex = i;
}
void CdbEngine::handlePid(const CdbExtensionCommandPtr &reply)
{
- if (reply->success) {
+ // Fails for core dumps.
+ if (reply->success)
notifyInferiorPid(reply->reply.toULongLong());
+ if (reply->success || startParameters().startMode == AttachCore) {
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupOk")
notifyInferiorSetupOk();
} else {
}
}
-// Parse CDB gdbmi register syntax
-static inline Register parseRegister(const GdbMi &gdbmiReg)
+// Parse CDB gdbmi register syntax.
+static Register parseRegister(const GdbMi &gdbmiReg)
{
Register reg;
reg.name = gdbmiReg.findChild("name").data();
reg.name += description.data();
reg.name += ')';
}
- reg.value = QString::fromAscii(gdbmiReg.findChild("value").data());
+ reg.value = gdbmiReg.findChild("value").data();
return reg;
}
if (state() == EngineSetupRequested) { // Temporary stop at beginning
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupOk")
notifyEngineSetupOk();
+ // Store stop reason to be handled in runEngine().
+ if (startParameters().startMode == AttachCore) {
+ m_coreStopReason.reset(new GdbMi);
+ m_coreStopReason->fromString(messageBA);
+ }
return;
}
+
GdbMi stopReason;
stopReason.fromString(messageBA);
processStop(stopReason, false);
}
// Notify about state and send off command sequence to get stack, etc.
if (stopFlags & StopNotifyStop) {
- if (state() == InferiorStopRequested) {
- STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorStopOk")
- notifyInferiorStopOk();
- } else {
- STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSpontaneousStop")
- notifyInferiorSpontaneousStop();
+ if (startParameters().startMode != AttachCore) {
+ if (state() == InferiorStopRequested) {
+ STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorStopOk")
+ notifyInferiorStopOk();
+ } else {
+ STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSpontaneousStop")
+ notifyInferiorSpontaneousStop();
+ }
}
// Prevent further commands from being sent if shutdown is in progress
if (stopFlags & StopShutdownInProgress) {
case BreakpointAtFork:
case WatchpointAtExpression:
case BreakpointAtSysCall:
+ case BreakpointOnQmlSignalHandler:
+ case BreakpointAtJavaScriptThrow:
return false;
case WatchpointAtAddress:
case BreakpointByFileAndLine:
}
switch (handler->state(id)) {
case BreakpointInsertRequested:
- if (parameters.type == BreakpointByFileAndLine) {
+ if (parameters.type == BreakpointByFileAndLine
+ && m_options->breakpointCorrection) {
if (lineCorrection.isNull())
lineCorrection.reset(new BreakpointCorrectionContext(debuggerCore()->cppCodeModelSnapshot(),
CPlusPlus::CppModelManagerInterface::instance()->workingCopy()));