void TermGdbAdapter::startAdapter()
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
    showMessage(_("TRYING TO START ADAPTER"));

// Currently, adapters are not re-used
//    // We leave the console open, so recycle it now.
//    m_stubProc.blockSignals(true);
//    m_stubProc.stop();
//    m_stubProc.blockSignals(false);

    if (!prepareCommand())
        return;

    m_stubProc.setWorkingDirectory(startParameters().workingDirectory);
    // Set environment + dumper preload.
    m_stubProc.setEnvironment(startParameters().environment);
    // FIXME: Starting the stub implies starting the inferior. This is
    // fairly unclean as far as the state machine and error reporting go.
    if (!m_stubProc.start(startParameters().executable,
                         startParameters().processArgs)) {
        // Error message for user is delivered via a signal.
        m_engine->handleAdapterStartFailed(QString(), QString());
        return;
    }

    if (!m_engine->startGdb()) {
        m_stubProc.stop();
        return;
    }
}
void PlainGdbAdapter::startAdapter()
{
    QTC_ASSERT(state() == EngineStarting, qDebug() << state());
    setState(AdapterStarting);
    debugMessage(_("TRYING TO START ADAPTER"));

    QStringList gdbArgs;

    if (!m_outputCollector.listen()) {
        emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
                .arg(m_outputCollector.errorString()), QString());
        return;
    }
    gdbArgs.append(_("--tty=") + m_outputCollector.serverName());

    if (!startParameters().workingDir.isEmpty())
        m_engine->m_gdbProc.setWorkingDirectory(startParameters().workingDir);
    if (!startParameters().environment.isEmpty())
        m_engine->m_gdbProc.setEnvironment(startParameters().environment);

    if (!m_engine->startGdb(gdbArgs)) {
        m_outputCollector.shutdown();
        return;
    }

    emit adapterStarted();
}
void LocalPlainGdbAdapter::startAdapter()
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
    showMessage(_("TRYING TO START ADAPTER"));

    if (!prepareCommand())
        return;

    QStringList gdbArgs;

    if (!m_outputCollector.listen()) {
        m_engine->handleAdapterStartFailed(tr("Cannot set up communication with child process: %1")
                .arg(m_outputCollector.errorString()), QString());
        return;
    }
    gdbArgs.append(_("--tty=") + m_outputCollector.serverName());

    if (!startParameters().workingDirectory.isEmpty())
        m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
    if (startParameters().environment.size())
        m_gdbProc.setEnvironment(startParameters().environment.toStringList());

    if (!m_engine->startGdb(gdbArgs)) {
        m_outputCollector.shutdown();
        return;
    }

    checkForReleaseBuild();
    m_engine->handleAdapterStarted();
}
void GdbRemoteServerEngine::callTargetRemote()
{
    QByteArray rawChannel = startParameters().remoteChannel.toLatin1();
    QByteArray channel = rawChannel;

    // Don't touch channels with explicitly set protocols.
    if (!channel.startsWith("tcp:") && !channel.startsWith("udp:")
            && !channel.startsWith("file:") && channel.contains(':')
            && !channel.startsWith('|'))
    {
        // "Fix" the IPv6 case with host names without '['...']'
        if (!channel.startsWith('[') && channel.count(':') >= 2) {
            channel.insert(0, '[');
            channel.insert(channel.lastIndexOf(':'), ']');
        }
        channel = "tcp:" + channel;
    }

    if (m_isQnxGdb)
        postCommand("target qnx " + channel, CB(handleTargetQnx));
    else if (startParameters().multiProcess)
        postCommand("target extended-remote " + channel, CB(handleTargetExtendedRemote));
    else
        postCommand("target remote " + channel, CB(handleTargetRemote), 10);
}
void RemoteGdbServerAdapter::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
    const DebuggerStartParameters &sp = startParameters();

    QString fileName;
    if (!sp.executable.isEmpty()) {
        QFileInfo fi(sp.executable);
        fileName = fi.absoluteFilePath();
    }
    const QByteArray sysroot = sp.sysroot.toLocal8Bit();
    const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
    const QByteArray gnuTarget = sp.gnuTarget.toLatin1();
    const QByteArray searchPath = startParameters().searchPath.toLocal8Bit();
    const QString args = sp.processArgs;

    if (!remoteArch.isEmpty())
        m_engine->postCommand("set architecture " + remoteArch);
    if (!gnuTarget.isEmpty())
        m_engine->postCommand("set gnutarget " + gnuTarget);
    if (!sysroot.isEmpty())
        m_engine->postCommand("set sysroot " + sysroot);
    if (!searchPath.isEmpty())
        m_engine->postCommand("set solib-search-path " + searchPath);
    if (!args.isEmpty())
        m_engine->postCommand("-exec-arguments " + args.toLocal8Bit());

    // This has to be issued before 'target remote'. On pre-7.0 the
    // command is not present and will result in ' No symbol table is
    // loaded.  Use the "file" command.' as gdb tries to set the
    // value of a variable with name 'target-async'.
    //
    // Testing with -list-target-features which was introduced at
    // the same time would not work either, as this need an existing
    // target.
    //
    // Using it even without a target and having it fail might still
    // be better as:
    // Some external comment: '[but] "set target-async on" with a native
    // windows gdb will work, but then fail when you actually do
    // "run"/"attach", I think..


    // gdb/mi/mi-main.c:1958: internal-error:
    // mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
    // failed.\nA problem internal to GDB has been detected,[...]
    if (debuggerCore()->boolSetting(TargetAsync))
        m_engine->postCommand("set target-async on", CB(handleSetTargetAsync));

    if (fileName.isEmpty()) {
        showMessage(tr("No symbol file given."), StatusBar);
        callTargetRemote();
        return;
    }

    m_engine->postCommand("-file-exec-and-symbols \""
        + fileName.toLocal8Bit() + '"',
        CB(handleFileExecAndSymbols));
}
Exemple #6
0
void GdbPlainEngine::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
    if (!startParameters().processArgs.isEmpty()) {
        QString args = startParameters().processArgs;
        postCommand("-exec-arguments " + toLocalEncoding(args));
    }
    postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
        CB(handleFileExecAndSymbols));
}
void PlainGdbAdapter::startInferior()
{
    QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
    if (!startParameters().processArgs.isEmpty())
        m_engine->postCommand(_("-exec-arguments ")
            + startParameters().processArgs.join(_(" ")));
    QFileInfo fi(startParameters().executable);
    m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()),
        CB(handleFileExecAndSymbols));
}
void GdbAttachEngine::setupEngine()
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
    showMessage(_("TRYING TO START ADAPTER"));

    if (!startParameters().workingDirectory.isEmpty())
        m_gdbProc->setWorkingDirectory(startParameters().workingDirectory);
    if (startParameters().environment.size())
        m_gdbProc->setEnvironment(startParameters().environment.toStringList());

    startGdb();
}
void RemotePlainGdbAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
    Q_UNUSED(gdbServerPort);
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());

    if (qmlPort != -1)
        startParameters().qmlServerPort = qmlPort;
    if (!startParameters().workingDirectory.isEmpty())
        m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
    if (startParameters().environment.size())
        m_gdbProc.setEnvironment(startParameters().environment.toStringList());
    m_gdbProc.realStart(m_engine->startParameters().debuggerCommand,
        QStringList() << QLatin1String("-i") << QLatin1String("mi"),
        m_engine->startParameters().executable);
}
void GdbCoreEngine::continueSetupEngine()
{
    bool isCore = true;
    if (m_coreUnpackProcess) {
        isCore = m_coreUnpackProcess->exitCode() == 0;
        m_coreUnpackProcess->deleteLater();
        m_coreUnpackProcess = 0;
        if (m_tempCoreFile.isOpen())
            m_tempCoreFile.close();
    }
    if (isCore && m_executable.isEmpty()) {
        GdbCoreEngine::CoreInfo cinfo = readExecutableNameFromCore(
                                            startParameters().debuggerCommand,
                                            coreFileName());

        if (cinfo.isCore) {
            m_executable = cinfo.foundExecutableName;
            if (m_executable.isEmpty()) {
                Core::AsynchronousMessageBox::warning(
                    tr("Error Loading Symbols"),
                    tr("No executable to load symbols from specified core."));
                notifyEngineSetupFailed();
                return;
            }
        }
    }
    if (isCore) {
        startGdb();
    } else {
        Core::AsynchronousMessageBox::warning(
            tr("Error Loading Core File"),
            tr("The specified file does not appear to be a core file."));
        notifyEngineSetupFailed();
    }
}
Exemple #11
0
void CoreGdbAdapter::handleTemporaryTargetCore(const GdbResponse &response)
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
    if (response.resultClass != GdbResultDone) {
        showMessage(tr("Attach to core failed."), StatusBar);
        m_engine->notifyEngineSetupFailed();
        return;
    }

    QByteArray console = response.consoleStreamOutput;
    int pos1 = console.indexOf('`');
    int pos2 = console.indexOf('\'');
    if (pos1 == -1 || pos2 == -1) {
        showMessage(tr("Attach to core failed."), StatusBar);
        m_engine->notifyEngineSetupFailed();
        return;
    }

    m_executable = console.mid(pos1 + 1, pos2 - pos1 - 1);
    // Strip off command line arguments. FIXME: make robust.
    int idx = m_executable.indexOf(_c(' '));
    if (idx >= 0)
        m_executable.truncate(idx);
    if (m_executable.isEmpty()) {
        m_engine->postCommand("detach");
        m_engine->notifyEngineSetupFailed();
        return;
    }
    m_executable = QFileInfo(startParameters().coreFile).absoluteDir()
                   .absoluteFilePath(m_executable);
    showMessage(tr("Attached to core temporarily."), StatusBar);
    m_engine->postCommand("detach", CB(handleTemporaryDetach));
}
void GdbRemoteServerEngine::callTargetRemote()
{
    //m_breakHandler->clearBreakMarkers();

    // "target remote" does three things:
    //     (1) connects to the gdb server
    //     (2) starts the remote application
    //     (3) stops the remote application (early, e.g. in the dynamic linker)
    QByteArray channel = startParameters().remoteChannel.toLatin1();

    // Don't touch channels with explicitly set protocols.
    if (!channel.startsWith("tcp:") && !channel.startsWith("udp:")
            && !channel.startsWith("file:") && channel.contains(':'))
    {
        // "Fix" the IPv6 case with host names without '['...']'
        if (!channel.startsWith('[') && channel.count(':') >= 2) {
            channel.insert(0, '[');
            channel.insert(channel.lastIndexOf(':'), ']');
        }
        channel = "tcp:" + channel;
    }

    if (m_isQnxGdb)
        postCommand("target qnx " + channel, CB(handleTargetQnx));
    else
        postCommand("target remote " + channel, CB(handleTargetRemote));
}
QString GdbCoreEngine::readExecutableNameFromCore(bool *isCore)
{
#if 0
    ElfReader reader(coreFileName());
    return QString::fromLocal8Bit(reader.readCoreName(isCore));
#else
    const DebuggerStartParameters &sp = startParameters();
    QStringList args;
    args.append(QLatin1String("-nx"));
    args.append(QLatin1String("-batch"));
    args.append(QLatin1String("-c"));
    args.append(coreFileName());
    QProcess proc;
    proc.start(sp.debuggerCommand, args);
    if (proc.waitForFinished()) {
        QByteArray ba = proc.readAllStandardOutput();
        // Core was generated by `/data/dev/creator-2.6/bin/qtcreator'.
        // Program terminated with signal 11, Segmentation fault.
        int pos1 = ba.indexOf("Core was generated by");
        if (pos1 != -1) {
            pos1 += 23;
            int pos2 = ba.indexOf('\'', pos1);
            if (pos2 != -1) {
                *isCore = true;
                return QString::fromLocal8Bit(ba.mid(pos1, pos2 - pos1));
            }
        }
    }
    return QString();
#endif
}
void RemoteGdbServerAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());

    if (qmlPort != -1)
        startParameters().qmlServerPort = qmlPort;
    if (gdbServerPort != -1) {
        QString &rc = startParameters().remoteChannel;
        const int sepIndex = rc.lastIndexOf(QLatin1Char(':'));
        if (sepIndex != -1) {
            rc.replace(sepIndex + 1, rc.count() - sepIndex - 1,
                       QString::number(gdbServerPort));
        }
    }
    handleSetupDone();
}
Exemple #15
0
void GdbPlainEngine::runEngine()
{
    if (startParameters().useContinueInsteadOfRun)
        postCommand("-exec-continue", GdbEngine::RunRequest, CB(handleExecuteContinue));
    else
        postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun));
}
void GdbAttachEngine::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
    const qint64 pid = startParameters().attachPID;
    postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
    // Task 254674 does not want to remove them
    //qq->breakHandler()->removeAllBreakpoints();
}
Exemple #17
0
bool AbstractGdbAdapter::prepareCommand()
{
#ifdef Q_OS_WIN
    Utils::QtcProcess::SplitError perr;
    startParameters().processArgs = Utils::QtcProcess::prepareArgs(
                startParameters().processArgs, &perr,
                &startParameters().environment, &startParameters().workingDirectory);
    if (perr != Utils::QtcProcess::SplitOk) {
        // perr == BadQuoting is never returned on Windows
        // FIXME? QTCREATORBUG-2809
        m_engine->handleAdapterStartFailed(QCoreApplication::translate("DebuggerEngine", // Same message in CdbEngine
            "Debugging complex command lines is currently not supported on Windows."), QString());
        return false;
    }
#endif
    return true;
}
void QmlCppEngine::setupEngine()
{
    EDEBUG("\nMASTER SETUP ENGINE");
    setActiveEngine(m_cppEngine);
    m_qmlEngine->setupSlaveEngine();
    m_cppEngine->setupSlaveEngine();

    if (startParameters().remoteSetupNeeded)
        notifyEngineRequestRemoteSetup();
}
void LocalPlainGdbAdapter::checkForReleaseBuild()
{
    QString objDump = _("objdump");
    // Windows: Locate objdump in the debuggee's (MinGW) environment
    if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS
        && startParameters().environment.size()) {
        objDump = startParameters().environment.searchInPath(objDump);
    } else {
        objDump = Utils::Environment::systemEnvironment().searchInPath(objDump);
    }
    if (objDump.isEmpty()) {
        showMessage(_("Could not locate objdump command for release build check"), LogWarning);
        return;
    }
    // Quick check for a "release" build
    QProcess proc;
    QStringList args;
    args.append(_("-h"));
    args.append(_("-j"));
    args.append(_(".debug_info"));
    args.append(startParameters().executable);
    proc.start(objDump, args);
    proc.closeWriteChannel();
    if (!proc.waitForStarted()) {
        showMessage(_("OBJDUMP PROCESS COULD NOT BE STARTED. "
            "RELEASE BUILD CHECK WILL FAIL"));
        return;
    }
    proc.waitForFinished();
    QByteArray ba = proc.readAllStandardOutput();
    // This should yield something like
    // "debuggertest:     file format elf32-i386\n\n"
    // "Sections:\nIdx Name          Size      VMA       LMA       File off  Algn\n"
    // "30 .debug_info   00087d36  00000000  00000000  0006bbd5  2**0\n"
    // " CONTENTS, READONLY, DEBUGGING"
    if (ba.contains("Sections:") && !ba.contains(".debug_info")) {
        showMessageBox(QMessageBox::Information, "Warning",
           tr("This does not seem to be a \"Debug\" build.\n"
              "Setting breakpoints by file name and line number may fail."));
    }
}
void GdbRemotePlainEngine::notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort)
{
    Q_UNUSED(gdbServerPort);
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());

    DebuggerStartParameters &sp = startParameters();
    if (qmlPort != -1)
        sp.qmlServerPort = qmlPort;
    m_gdbProc.realStart(sp.debuggerCommand,
        QStringList() << QLatin1String("-i") << QLatin1String("mi"),
        sp.executable);
}
Exemple #21
0
void CoreGdbAdapter::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
    // Do that first, otherwise no symbols are loaded.
    QFileInfo fi(m_executable);
    const QByteArray sysroot = startParameters().sysroot.toLocal8Bit();
    QByteArray path = fi.absoluteFilePath().toLocal8Bit();
    if (!sysroot.isEmpty())
        m_engine->postCommand("set sysroot " + sysroot);
    m_engine->postCommand("-file-exec-and-symbols \"" + path + '"',
         CB(handleFileExecAndSymbols));
}
void RemoteGdbServerAdapter::callTargetRemote()
{
    //m_breakHandler->clearBreakMarkers();

    // "target remote" does three things:
    //     (1) connects to the gdb server
    //     (2) starts the remote application
    //     (3) stops the remote application (early, e.g. in the dynamic linker)
    QString channel = startParameters().remoteChannel;
    m_engine->postCommand("target remote " + channel.toLatin1(),
        CB(handleTargetRemote));
}
void GdbCoreEngine::setupEngine()
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
    showMessage(_("TRYING TO START ADAPTER"));

    const DebuggerStartParameters &sp = startParameters();
    m_executable = sp.executable;
    QFileInfo fi(sp.coreFile);
    m_coreName = fi.absoluteFilePath();

    unpackCoreIfNeeded();
}
void RemoteGdbAdapter::startAdapter()
{
    QTC_ASSERT(state() == EngineStarting, qDebug() << state());
    setState(AdapterStarting);
    debugMessage(_("TRYING TO START ADAPTER"));

    // FIXME: make asynchroneous
    // Start the remote server
    if (startParameters().serverStartScript.isEmpty()) {
        m_engine->showStatusMessage(_("No server start script given. "
                                      "Assuming server runs already."));
    } else {
        m_uploadProc.start(_("/bin/sh ") + startParameters().serverStartScript);
        m_uploadProc.waitForStarted();
    }

    if (!m_engine->startGdb(QStringList(), startParameters().debuggerCommand))
        // FIXME: cleanup missing
        return;

    emit adapterStarted();
}
void GdbRemoteServerEngine::runEngine()
{
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());

    const QString remoteExecutable = startParameters().remoteExecutable;
    if (!remoteExecutable.isEmpty()) {
        // Cannot use -exec-run for QNX gdb 7.4 as it does not support path parameter for the MI call
        const bool useRun = m_isQnxGdb && m_gdbVersion > 70300;
        const QByteArray command = useRun ? "run" : "-exec-run";
        postCommand(command + " " + remoteExecutable.toLocal8Bit(), GdbEngine::RunRequest, CB(handleExecRun));
    } else {
        notifyEngineRunAndInferiorStopOk();
        continueInferiorInternal();
    }
}
Exemple #26
0
void PdbEngine::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());

    QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
    QFile scriptFile(fileName);
    if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
        showMessageBox(QMessageBox::Critical, tr("Python Error"),
            _("Cannot open script file %1:\n%2").
               arg(fileName, scriptFile.errorString()));
        notifyInferiorSetupFailed();
        return;
    }
    notifyInferiorSetupOk();
}
Exemple #27
0
void PdbEngine::runEngine()
{
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
    showStatusMessage(tr("Running requested..."), 5000);
    const QByteArray dumperSourcePath =
        Core::ICore::resourcePath().toLocal8Bit() + "/dumper/";
    QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
    postDirectCommand("import sys");
    postDirectCommand("sys.argv.append('" + fileName.toLocal8Bit() + "')");
    postDirectCommand("execfile('/usr/bin/pdb')");
    postDirectCommand("execfile('" + dumperSourcePath + "pdumper.py')");
    attemptBreakpointSynchronization();
    notifyEngineRunAndInferiorStopOk();
    continueInferior();
}
void CoreGdbAdapter::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
    // Do that first, otherwise no symbols are loaded.
    QFileInfo fi(m_executable);
    const QByteArray sysroot = startParameters().sysroot.toLocal8Bit();
    QByteArray path = fi.absoluteFilePath().toLocal8Bit();
    if (!sysroot.isEmpty()) {
        m_engine->postCommand("set sysroot " + sysroot);
        // sysroot is not enough to correctly locate the sources, so explicitly
        // relocate the most likely place for the debug source
        m_engine->postCommand("set substitute-path /usr/src " + sysroot + "/usr/src");
    }
    m_engine->postCommand("-file-exec-and-symbols \"" + path + '"',
         CB(handleFileExecAndSymbols));
}
void GdbRemotePlainEngine::setupEngine()
{
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
    showMessage(QLatin1String("TRYING TO START ADAPTER"));

    if (!startParameters().workingDirectory.isEmpty())
        m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
    if (startParameters().environment.size())
        m_gdbProc.setEnvironment(startParameters().environment.toStringList());

    notifyEngineRemoteSetupDone(startParameters().connParams.port, startParameters().qmlServerPort);
}
void ScriptEngine::setupInferior()
{
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
    m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
    showMessage(_("SCRIPT FILE: ") + m_scriptFileName);
    QFile scriptFile(m_scriptFileName);
    if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
        showMessageBox(QMessageBox::Critical, tr("Error:"),
            _("Cannot open script file %1:\n%2").
          arg(m_scriptFileName, scriptFile.errorString()));
        notifyInferiorSetupFailed();
        return;
    }
    QTextStream stream(&scriptFile);
    m_scriptContents = stream.readAll();
    scriptFile.close();
    attemptBreakpointSynchronization();
    notifyInferiorSetupOk();
}