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)); }
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(); } }
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(); }
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(); }
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); }
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(); } }
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(); }
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(); }