Пример #1
0
bool ConsoleProcess::start(const QString &program, const QString &args)
{
    if (isRunning())
        return false;

    d->m_errorString.clear();
    d->m_error = QProcess::UnknownError;

    QString pcmd;
    QString pargs;
    if (d->m_mode != Run) { // The debugger engines already pre-process the arguments.
        pcmd = program;
        pargs = args;
    } else {
        QtcProcess::Arguments outArgs;
        QtcProcess::prepareCommand(program, args, &pcmd, &outArgs, OsTypeWindows,
                                   &d->m_environment, &d->m_workingDir);
        pargs = outArgs.toWindowsArgs();
    }

    const QString err = stubServerListen();
    if (!err.isEmpty()) {
        emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
        return false;
    }

    QStringList env = d->m_environment.toStringList();
    if (!env.isEmpty()) {
        d->m_tempFile = new QTemporaryFile();
        if (!d->m_tempFile->open()) {
            stubServerShutdown();
            emitError(QProcess::FailedToStart, msgCannotCreateTempFile(d->m_tempFile->errorString()));
            delete d->m_tempFile;
            d->m_tempFile = 0;
            return false;
        }
        QTextStream out(d->m_tempFile);
        out.setCodec("UTF-16LE");
        out.setGenerateByteOrderMark(false);
        foreach (const QString &var, fixWinEnvironment(env))
            out << var << QChar(0);
        out << QChar(0);
        out.flush();
        if (out.status() != QTextStream::Ok) {
            stubServerShutdown();
            emitError(QProcess::FailedToStart, msgCannotWriteTempFile());
            delete d->m_tempFile;
            d->m_tempFile = 0;
            return false;
        }
    }
Пример #2
0
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();
        }
    };
Пример #3
0
// 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);
}