void LldbEngine::setupInferior() { Environment sysEnv = Environment::systemEnvironment(); Environment runEnv = runParameters().inferior.environment; foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) { DebuggerCommand cmd("executeDebuggerCommand"); if (item.unset) cmd.arg("command", "settings remove target.env-vars " + item.name); else cmd.arg("command", "settings set target.env-vars '" + item.name + '=' + item.value + '\''); runCommand(cmd); } const QString path = stringSetting(ExtraDumperFile); if (!path.isEmpty() && QFileInfo(path).isReadable()) { DebuggerCommand cmd("addDumperModule"); cmd.arg("path", path); runCommand(cmd); } const QString commands = stringSetting(ExtraDumperCommands); if (!commands.isEmpty()) { DebuggerCommand cmd("executeDebuggerCommand"); cmd.arg("command", commands); runCommand(cmd); } DebuggerCommand cmd1("loadDumpers"); cmd1.callback = [this](const DebuggerResponse &response) { watchHandler()->addDumpers(response.data["dumpers"]); }; runCommand(cmd1); const DebuggerRunParameters &rp = runParameters(); QString executable; QtcProcess::Arguments args; QtcProcess::prepareCommand(QFileInfo(rp.inferior.executable).absoluteFilePath(), rp.inferior.commandLineArguments, &executable, &args); DebuggerCommand cmd2("setupInferior"); cmd2.arg("executable", executable); cmd2.arg("breakonmain", rp.breakOnMain); cmd2.arg("useterminal", rp.useTerminal); cmd2.arg("startmode", rp.startMode); cmd2.arg("nativemixed", isNativeMixedActive()); cmd2.arg("dyldimagesuffix", rp.inferior.environment.value("DYLD_IMAGE_SUFFIX")); cmd2.arg("dyldframeworkpath", rp.inferior.environment.value("DYLD_LIBRARY_PATH")); cmd2.arg("dyldlibrarypath", rp.inferior.environment.value("DYLD_FRAMEWORK_PATH")); QJsonArray processArgs; foreach (const QString &arg, args.toUnixArgs()) processArgs.append(QLatin1String(arg.toUtf8().toHex())); cmd2.arg("processargs", processArgs); if (rp.useTerminal) { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); const qint64 attachedPID = m_stubProc.applicationPID(); const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID(); const QString msg = (attachedMainThreadID != -1) ? QString::fromLatin1("Attaching to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID) : QString::fromLatin1("Attaching to %1").arg(attachedPID); showMessage(msg, LogMisc); cmd2.arg("attachpid", attachedPID); } else { cmd2.arg("startmode", rp.startMode); // it is better not to check the start mode on the python sid (as we would have to duplicate the // enum values), and thus we assume that if the rp.attachPID is valid we really have to attach QTC_CHECK(rp.attachPID <= 0 || (rp.startMode == AttachCrashedExternal || rp.startMode == AttachExternal)); cmd2.arg("attachpid", rp.attachPID); cmd2.arg("sysroot", rp.deviceSymbolsRoot.isEmpty() ? rp.sysRoot : rp.deviceSymbolsRoot); cmd2.arg("remotechannel", ((rp.startMode == AttachToRemoteProcess || rp.startMode == AttachToRemoteServer) ? rp.remoteChannel : QString())); cmd2.arg("platform", rp.platform); QTC_CHECK(!rp.continueAfterAttach || (rp.startMode == AttachToRemoteProcess || rp.startMode == AttachExternal || rp.startMode == AttachToRemoteServer)); m_continueAtNextSpontaneousStop = false; } cmd2.callback = [this](const DebuggerResponse &response) { bool success = response.data["success"].toInt(); if (success) { foreach (Breakpoint bp, breakHandler()->unclaimedBreakpoints()) { if (acceptsBreakpoint(bp)) { bp.setEngine(this); insertBreakpoint(bp); } else { showMessage(QString("BREAKPOINT %1 IN STATE %2 IS NOT ACCEPTABLE") .arg(bp.id().toString()).arg(bp.state())); } } notifyInferiorSetupOk(); } else { notifyInferiorSetupFailed(); } };
// FIXME: splitting of setupInferior() necessary to support LLDB <= 310 - revert asap void LldbEngine::setupInferiorStage2() { const DebuggerRunParameters &rp = runParameters(); QString executable; QtcProcess::Arguments args; QtcProcess::prepareCommand(QFileInfo(rp.executable).absoluteFilePath(), rp.processArgs, &executable, &args); DebuggerCommand cmd("setupInferior"); cmd.arg("executable", executable); cmd.arg("breakOnMain", rp.breakOnMain); cmd.arg("useTerminal", rp.useTerminal); cmd.arg("startMode", rp.startMode); cmd.beginList("bkpts"); foreach (Breakpoint bp, breakHandler()->unclaimedBreakpoints()) { if (acceptsBreakpoint(bp)) { showMessage(_("TAKING OWNERSHIP OF BREAKPOINT %1 IN STATE %2") .arg(bp.id().toString()).arg(bp.state())); bp.setEngine(this); bp.notifyBreakpointInsertProceeding(); cmd.beginGroup(); bp.addToCommand(&cmd); cmd.endGroup(); } else { showMessage(_("BREAKPOINT %1 IN STATE %2 IS NOT ACCEPTABLE") .arg(bp.id().toString()).arg(bp.state())); } } cmd.endList(); cmd.beginList("processArgs"); foreach (const QString &arg, args.toUnixArgs()) cmd.arg(arg.toUtf8().toHex()); cmd.endList(); if (rp.useTerminal) { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); const qint64 attachedPID = m_stubProc.applicationPID(); const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID(); const QString msg = (attachedMainThreadID != -1) ? QString::fromLatin1("Attaching to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID) : QString::fromLatin1("Attaching to %1").arg(attachedPID); showMessage(msg, LogMisc); cmd.arg("attachPid", attachedPID); } else { cmd.arg("startMode", rp.startMode); // it is better not to check the start mode on the python sid (as we would have to duplicate the // enum values), and thus we assume that if the rp.attachPID is valid we really have to attach QTC_CHECK(rp.attachPID <= 0 || (rp.startMode == AttachCrashedExternal || rp.startMode == AttachExternal)); cmd.arg("attachPid", rp.attachPID); cmd.arg("sysRoot", rp.deviceSymbolsRoot.isEmpty() ? rp.sysRoot : rp.deviceSymbolsRoot); cmd.arg("remoteChannel", ((rp.startMode == AttachToRemoteProcess || rp.startMode == AttachToRemoteServer) ? rp.remoteChannel : QString())); cmd.arg("platform", rp.platform); QTC_CHECK(!rp.continueAfterAttach || (rp.startMode == AttachToRemoteProcess || rp.startMode == AttachExternal || rp.startMode == AttachToRemoteServer)); m_continueAtNextSpontaneousStop = false; } runCommand(cmd); }