ios simulator debugging

Change-Id: Ieee4a509b46da937c3bce21f72c77685946db4dd
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
Fawzi Mohamed
2013-10-10 15:15:49 +02:00
committed by hjk
parent dc5ba1127d
commit c162ba1391
12 changed files with 213 additions and 28 deletions

View File

@@ -312,7 +312,7 @@ void IosConfigurations::updateAutomaticKitList()
//DeviceKitInformation::setDevice(newKit, device);
Debugger::DebuggerItem debugger;
debugger.setCommand(pToolchain->suggestedDebugger());
debugger.setCommand(pToolchain->suggestedDebugger()); // use lldbPath() instead?
debugger.setEngineType(Debugger::LldbEngineType);
debugger.setDisplayName(tr("IOS Debugger"));
debugger.setAutoDetected(true);
@@ -371,6 +371,11 @@ FileName IosConfigurations::developerPath()
return m_instance->m_developerPath;
}
FileName IosConfigurations::lldbPath()
{
return m_instance->m_lldbPath;
}
void IosConfigurations::save()
{
QSettings *settings = Core::ICore::settings();
@@ -432,6 +437,18 @@ void IosConfigurations::setDeveloperPath(const FileName &devPath)
m_instance->m_developerPath = devPath;
m_instance->save();
updateAutomaticKitList();
QProcess lldbInfo;
lldbInfo.start(QLatin1String("xcrun"), QStringList() << QLatin1String("--find")
<< QLatin1String("lldb"));
if (!lldbInfo.waitForFinished(2000)) {
lldbInfo.kill();
} else {
QByteArray lPath=lldbInfo.readAll();
lPath.chop(1);
Utils::FileName lldbPath = Utils::FileName::fromString(QString::fromLocal8Bit(lPath.data(), lPath.size()));
if (lldbPath.toFileInfo().exists())
m_instance->m_lldbPath = lldbPath;
}
emit m_instance->updated();
}
}

View File

@@ -53,6 +53,7 @@ public:
static bool ignoreAllDevices();
static void setIgnoreAllDevices(bool ignoreDevices);
static Utils::FileName developerPath();
static Utils::FileName lldbPath();
signals:
void updated();
@@ -68,6 +69,7 @@ private:
static void setDeveloperPath(const Utils::FileName &devPath);
Utils::FileName m_developerPath;
Utils::FileName m_lldbPath;
bool m_ignoreAllDevices;
};

View File

@@ -37,7 +37,8 @@
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/target.h>
#include <qt4projectmanager/qmakebuildconfiguration.h>
#include <qt4projectmanager/qmakenodes.h>
@@ -45,6 +46,11 @@
#include <qtsupport/qtkitinformation.h>
#include <QDir>
#include <QTcpServer>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
using namespace Debugger;
using namespace ProjectExplorer;
@@ -56,14 +62,46 @@ namespace Internal {
RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfig,
QString *errorMessage)
{
//Target *target = runConfig->target();
//Qt4Project *project = static_cast<Qt4Project *>(target->project());
Target *target = runConfig->target();
if (!target)
return 0;
ProjectExplorer::IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
if (device.isNull())
return 0;
Qt4Project *project = static_cast<Qt4Project *>(target->project());
DebuggerStartParameters params;
params.startMode = AttachToRemoteServer;
//params.displayName = IosManager::packageName(target);
if (device->type() == Core::Id(Ios::Constants::IOS_DEVICE_TYPE))
params.startMode = AttachToRemoteProcess;
else
params.startMode = AttachExternal;
params.displayName = runConfig->appName();
params.remoteSetupNeeded = true;
Debugger::DebuggerRunConfigurationAspect *aspect
= runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
if (aspect->useCppDebugger()) {
params.languages |= CppLanguage;
Kit *kit = target->kit();
params.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
if (ToolChain *tc = ToolChainKitInformation::toolChain(kit))
params.toolChainAbi = tc->targetAbi();
params.executable = runConfig->exePath().toString();
}
if (aspect->useQmlDebugger()) {
params.languages |= QmlLanguage;
QTcpServer server;
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|| server.listen(QHostAddress::LocalHostIPv6), return 0);
params.qmlServerAddress = server.serverAddress().toString();
params.remoteSetupNeeded = true;
//TODO: Not sure if these are the right paths.
params.projectSourceDirectory = project->projectDirectory();
params.projectSourceFiles = project->files(Qt4Project::ExcludeGeneratedFiles);
params.projectBuildDirectory = project->rootQt4ProjectNode()->buildDir();
}
DebuggerRunControl * const debuggerRunControl
= DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
new IosDebugSupport(runConfig, debuggerRunControl);
@@ -74,7 +112,7 @@ IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
DebuggerRunControl *runControl)
: QObject(runControl), m_runControl(runControl),
m_runner(new IosRunner(this, runConfig, true)),
m_gdbServerPort(0), m_qmlPort(0)
m_gdbServerFd(0), m_qmlPort(0)
{
connect(m_runControl->engine(), SIGNAL(requestRemoteSetup()),
@@ -84,6 +122,8 @@ IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
connect(m_runner, SIGNAL(gotGdbSocket(int)),
SLOT(handleGdbServerFd(int)));
connect(m_runner, SIGNAL(gotInferiorPid(Q_PID)),
SLOT(handleGotInferiorPid(Q_PID)));
connect(m_runner, SIGNAL(finished(bool)),
SLOT(handleRemoteProcessFinished(bool)));
@@ -93,17 +133,43 @@ IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
SLOT(handleRemoteOutput(QString)));
}
IosDebugSupport::~IosDebugSupport()
{
if (m_gdbServerFd > 0)
close(m_gdbServerFd);
}
void IosDebugSupport::handleGdbServerFd(int gdbServerFd)
{
Q_UNUSED(gdbServerFd);
QTC_CHECK(false); // to do transfer fd to debugger
//m_runControl->engine()->notifyEngineRemoteSetupDone(gdbServerPort, qmlPort);
if (m_gdbServerFd > 0) {
close(m_gdbServerFd);
m_gdbServerFd = 0;
}
if (gdbServerFd > 0) {
m_runControl->engine()->notifyEngineRemoteSetupDone(m_gdbServerFd, m_qmlPort);
} else {
m_runControl->engine()->notifyEngineRemoteSetupFailed(
tr("Could not get debug server file descriptor."));
}
}
void IosDebugSupport::handleGotInferiorPid(Q_PID pid)
{
if (pid > 0) {
//m_runControl->engine()->notifyInferiorPid(pid);
m_runControl->engine()->notifyEngineRemoteSetupDone(int(pid), m_qmlPort);
} else {
m_runControl->engine()->notifyEngineRemoteSetupFailed(
tr("Got an invalid process id."));
}
}
void IosDebugSupport::handleRemoteProcessFinished(bool cleanEnd)
{
if (!cleanEnd && m_runControl)
m_runControl->showMessage(tr("Run failed unexpectedly."), AppStuff);
//m_runControl->engine()->notifyInferiorIll();
m_runControl->engine()->abortDebugger();
}
void IosDebugSupport::handleRemoteOutput(const QString &output)

View File

@@ -30,6 +30,7 @@
#define IOSDEBUGSUPPORT_H
#include "iosrunconfiguration.h"
#include <QProcess>
namespace Debugger { class DebuggerRunControl; }
namespace ProjectExplorer { class RunControl; }
@@ -50,9 +51,11 @@ public:
IosDebugSupport(IosRunConfiguration *runConfig,
Debugger::DebuggerRunControl *runControl);
~IosDebugSupport();
private slots:
void handleGdbServerFd(int gdbServerFd);
void handleGotInferiorPid(Q_PID);
void handleRemoteProcessFinished(bool cleanEnd);
void handleRemoteOutput(const QString &output);
@@ -63,7 +66,7 @@ private:
IosRunner * const m_runner;
const QString m_dumperLib;
int m_gdbServerPort;
int m_gdbServerFd;
int m_qmlPort;
};

View File

@@ -214,6 +214,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco
}
if (hasClang) {
Platform clangProfile;
clangProfile.developerPath = Utils::FileName::fromString(devPath);
clangProfile.platformKind = 0;
clangProfile.name = clangFullName;
clangProfile.platformPath = Utils::FileName(fInfo);
@@ -231,6 +232,7 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco
}
if (hasGcc) {
Platform gccProfile;
gccProfile.developerPath = Utils::FileName::fromString(devPath);
gccProfile.name = gccFullName;
gccProfile.platformKind = 0;
// use the arm-apple-darwin10-llvm-* variant and avoid the extraFlags if available???

View File

@@ -41,6 +41,7 @@
#include <QCoreApplication>
#include <QList>
#include <QScopedArrayPointer>
#include <QProcessEnvironment>
#if defined(Q_OS_UNIX)
#include <sys/types.h>
@@ -65,6 +66,7 @@ class MyProcess: public QProcess
Q_OBJECT
public:
explicit MyProcess(QObject *parent = 0);
~MyProcess();
int processOutputSocket();
QSocketNotifier *notifier();
protected:
@@ -224,10 +226,15 @@ MyProcess::MyProcess(QObject *parent) : QProcess(parent)
if (socketpair(PF_UNIX, SOCK_STREAM, 0, &m_sockets[0]) == -1) {
qDebug() << "IosToolHandler socketpair failed ";
}
shutdown(m_sockets[0], SHUT_WR);
m_notifier = new QSocketNotifier(m_sockets[0], QSocketNotifier::Read, this);
}
MyProcess::~MyProcess()
{
::close(m_sockets[0]);
::close(m_sockets[1]);
}
int MyProcess::processOutputSocket()
{
return m_sockets[0];
@@ -245,7 +252,6 @@ void MyProcess::setupChildProcess()
emit finished(-1, QProcess::CrashExit);
exit(-1);
}
shutdown(1, SHUT_RD); // leave open for handshake when transferring fd?
}
#else
MyProcess::MyProcess(QObject *parent) : QProcess(parent)
@@ -272,6 +278,11 @@ IosToolHandlerPrivate::IosToolHandlerPrivate(IosToolHandler::DeviceType devType,
q(q), state(NonStarted), devType(devType), buffer(4*lookaheadSize, 0), iBegin(0), iEnd(0),
gdbSocket(-1)
{
QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
foreach (const QString &k, env.keys())
if (k.startsWith(QLatin1String("DYLD_")))
env.remove(k);
process.setProcessEnvironment(env);
QObject::connect(process.notifier(), SIGNAL(activated(int)), q, SLOT(subprocessHasData(int)));
QObject::connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)),
q, SLOT(subprocessFinished(int,QProcess::ExitStatus)));
@@ -498,6 +509,8 @@ int recv_fd(int socket)
if ( (control_message->cmsg_level == SOL_SOCKET) &&
(control_message->cmsg_type == SCM_RIGHTS) ) {
sent_fd = *((int *) CMSG_DATA(control_message));
// aknowledge fd
send(socket, "x", 1, 0);
return sent_fd;
}
}
@@ -777,7 +790,7 @@ void IosToolHandlerPrivate::subprocessHasData(int socket)
currentData = buffer.mid(0, lastXmlSize); // remove this??
}
qptrdiff toRead = lookaheadSize - (iEnd - spacerStart);
qptrdiff reallyRead = recv(socket, buffer.data() + iBegin, toRead, 0);
qptrdiff reallyRead = recv(socket, buffer.data() + iEnd, toRead, 0);
if (reallyRead == 0) { // eof
stop();
return;
@@ -799,14 +812,19 @@ void IosToolHandlerPrivate::subprocessHasData(int socket)
iEnd += reallyRead;
if (reallyRead != toRead)
continue;
if (spacerStart < iEnd && buffer.at(spacerStart) != 'n') {
if (spacerStart < iEnd && buffer.at(spacerStart) != 'N') {
++spacerStart;
while (spacerStart < iEnd && buffer.at(spacerStart) != 'n')
while (spacerStart < iEnd && buffer.at(spacerStart) != 'N')
++spacerStart;
continue;
}
}
if (buffer.at(iEnd-1) != 'd') {
qDebug() << "IosToolHandler: bad alignment of spacer: " << buffer.mid(iBegin, iEnd - iBegin);
return;
}
gdbSocket = recv_fd(socket);
qDebug() << "IosToolHandler: receivedSocket";
gotGdbserverSocket(bundlePath, deviceId, gdbSocket);
stop();
return;