Commit 066efcd6 authored by hjk's avatar hjk

Debugging on Android

This implements the host side of
https://codereview.qt-project.org/#change,50290

Change-Id: I13c7df29534a2a85202c2b295b139896443b0120
Reviewed-by: default avatarEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
Reviewed-by: default avatarBogDan Vatra <bogdan@kde.org>
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 63f3a510
......@@ -135,7 +135,11 @@ AndroidDebugSupport::AndroidDebugSupport(AndroidRunConfiguration *runConfig,
m_runner, SLOT(start()));
connect(m_runControl, SIGNAL(finished()),
m_runner, SLOT(stop()));
connect(m_runControl->engine(), SIGNAL(aboutToNotifyInferiorSetupOk()),
m_runner, SLOT(handleGdbRunning()));
connect(m_runner, SIGNAL(remoteServerRunning(QByteArray,int)),
SLOT(handleRemoteServerRunning(QByteArray,int)));
connect(m_runner, SIGNAL(remoteProcessStarted(int,int)),
SLOT(handleRemoteProcessStarted(int,int)));
connect(m_runner, SIGNAL(remoteProcessFinished(QString)),
......@@ -147,6 +151,11 @@ AndroidDebugSupport::AndroidDebugSupport(AndroidRunConfiguration *runConfig,
SLOT(handleRemoteOutput(QByteArray)));
}
void AndroidDebugSupport::handleRemoteServerRunning(const QByteArray &serverChannel, int pid)
{
m_runControl->engine()->notifyEngineRemoteServerRunning(serverChannel, pid);
}
void AndroidDebugSupport::handleRemoteProcessStarted(int gdbServerPort, int qmlPort)
{
disconnect(m_runner, SIGNAL(remoteProcessStarted(int,int)),
......
......@@ -53,7 +53,8 @@ public:
Debugger::DebuggerRunControl *runControl);
private slots:
void handleRemoteProcessStarted(int gdbServerPort = -1, int qmlPort = -1);
void handleRemoteServerRunning(const QByteArray &serverChannel, int pid);
void handleRemoteProcessStarted(int gdbServerPort, int qmlPort);
void handleRemoteProcessFinished(const QString &errorMsg);
void handleRemoteOutput(const QByteArray &output);
......
This diff is collapsed.
......@@ -56,9 +56,11 @@ public:
public slots:
void start();
void stop();
void handleGdbRunning();
signals:
void remoteProcessStarted(int gdbServerPort = -1, int qmlPort = -1);
void remoteServerRunning(const QByteArray &serverChannel, int pid);
void remoteProcessStarted(int gdbServerPort, int qmlPort);
void remoteProcessFinished(const QString &errString = QString());
void remoteOutput(const QByteArray &output);
......@@ -69,29 +71,41 @@ private slots:
void checkPID();
void logcatReadStandardError();
void logcatReadStandardOutput();
void startLogcat();
void asyncStart();
private:
void adbKill(qint64 pid, const QString &device, int timeout = 2000, const QString &runAsPackageName = QString());
void adbKill(qint64 pid);
QStringList selector() const { return m_selector; }
void forceStop();
QByteArray runPs();
void findPs();
private:
QProcess m_adbLogcatProcess;
QTimer m_checkPIDTimer;
bool m_wasStarted;
QByteArray m_logcat;
QString m_intentName;
QString m_packageName;
QString m_deviceSerialNumber;
qint64 m_processPID;
qint64 m_gdbserverPID;
QTimer m_checkPIDTimer;
bool m_useCppDebugger;
bool m_useQmlDebugger;
QString m_remoteGdbChannel;
ushort m_localGdbServerPort; // Local end of forwarded debug socket.
uint m_qmlPort;
bool m_useLocalQtLibs;
QString m_pingFile;
QString m_pongFile;
QString m_gdbserverPath;
QString m_gdbserverCommand;
QString m_gdbserverSocket;
QString m_localLibs;
QString m_localJars;
QString m_localJarsInitClasses;
QString m_adb;
bool m_isBusyBox;
QStringList m_selector;
QMutex m_mutex;
};
......
......@@ -879,6 +879,11 @@ void DebuggerEngine::notifyEngineRequestRemoteSetup()
emit requestRemoteSetup();
}
void DebuggerEngine::notifyEngineRemoteServerRunning(const QByteArray &, int /*pid*/)
{
showMessage(_("NOTE: REMOTE SERVER RUNNING IN MULTIMODE"));
}
void DebuggerEngine::notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort)
{
showMessage(_("NOTE: REMOTE SETUP DONE: GDB SERVER PORT: %1 QML PORT %2")
......
......@@ -299,6 +299,7 @@ protected:
virtual void notifyEngineRequestRemoteSetup();
public:
virtual void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
virtual void notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort);
virtual void notifyEngineRemoteSetupFailed(const QString &message);
......
......@@ -1267,6 +1267,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
bool GdbEngine::acceptsDebuggerCommands() const
{
return true;
return state() == InferiorStopOk
|| state() == InferiorUnrunnable;
}
......@@ -3740,7 +3741,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response)
selectThread(other);
}
updateViews(); // Adjust Threads combobox.
if (m_hasInferiorThreadList && debuggerCore()->boolSetting(ShowThreadNames)) {
if (false && m_hasInferiorThreadList && debuggerCore()->boolSetting(ShowThreadNames)) {
postCommand("threadnames " +
debuggerCore()->action(MaximalStackDepth)->value().toByteArray(),
Discardable, CB(handleThreadNames));
......
......@@ -60,6 +60,8 @@ namespace Internal {
GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerStartParameters &startParameters)
: GdbEngine(startParameters)
{
m_isMulti = false;
m_targetPid = -1;
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
SLOT(uploadProcError(QProcess::ProcessError)));
connect(&m_uploadProc, SIGNAL(readyReadStandardOutput()),
......@@ -261,13 +263,8 @@ void GdbRemoteServerEngine::handleFileExecAndSymbols(const GdbResponse &response
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();
QByteArray rawChannel = startParameters().remoteChannel.toLatin1();
QByteArray channel = rawChannel;
// Don't touch channels with explicitly set protocols.
if (!channel.startsWith("tcp:") && !channel.startsWith("udp:")
......@@ -283,14 +280,16 @@ void GdbRemoteServerEngine::callTargetRemote()
if (m_isQnxGdb)
postCommand("target qnx " + channel, CB(handleTargetQnx));
else if (m_isMulti)
postCommand("target extended-remote " + m_serverChannel, CB(handleTargetExtendedRemote));
else
postCommand("target remote " + channel, CB(handleTargetRemote));
postCommand("target remote " + channel, CB(handleTargetRemote), 10);
}
void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &record)
void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (record.resultClass == GdbResultDone) {
if (response.resultClass == GdbResultDone) {
// gdb server will stop the remote application itself.
showMessage(_("INFERIOR STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
......@@ -303,11 +302,50 @@ void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &record)
} else {
// 16^error,msg="hd:5555: Connection timed out."
QString msg = msgConnectRemoteServerFailed(
QString::fromLocal8Bit(record.data.findChild("msg").data()));
QString::fromLocal8Bit(response.data.findChild("msg").data()));
notifyInferiorSetupFailed(msg);
}
}
void GdbRemoteServerEngine::handleTargetExtendedRemote(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
// gdb server will stop the remote application itself.
showMessage(_("ATTACHED TO GDB SERVER STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
QString postAttachCommands = debuggerCore()->stringSetting(GdbPostAttachCommands);
if (!postAttachCommands.isEmpty()) {
foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n')))
postCommand(cmd.toLatin1());
}
postCommand("attach " + QByteArray::number(m_targetPid), CB(handleTargetExtendedAttach));
} else {
QString msg = msgConnectRemoteServerFailed(
QString::fromLocal8Bit(response.data.findChild("msg").data()));
notifyInferiorSetupFailed(msg);
}
}
void GdbRemoteServerEngine::handleTargetExtendedAttach(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
// gdb server will stop the remote application itself.
handleInferiorPrepared();
} else {
QString msg = msgConnectRemoteServerFailed(
QString::fromLocal8Bit(response.data.findChild("msg").data()));
notifyInferiorSetupFailed(msg);
}
}
void GdbRemoteServerEngine::notifyInferiorSetupOk()
{
emit aboutToNotifyInferiorSetupOk();
GdbEngine::notifyInferiorSetupOk();
}
void GdbRemoteServerEngine::handleTargetQnx(const GdbResponse &response)
{
QTC_ASSERT(m_isQnxGdb, qDebug() << m_isQnxGdb);
......@@ -417,22 +455,36 @@ void GdbRemoteServerEngine::shutdownEngine()
notifyAdapterShutdownOk();
}
void GdbRemoteServerEngine::notifyEngineRemoteServerRunning
(const QByteArray &serverChannel, int inferiorPid)
{
showMessage(_("NOTE: REMOTE SERVER RUNNING IN MULTIMODE"));
m_isMulti = true;
m_targetPid = inferiorPid;
m_serverChannel = serverChannel;
startGdb();
}
void GdbRemoteServerEngine::notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort)
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
DebuggerEngine::notifyEngineRemoteSetupDone(gdbServerPort, qmlPort);
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));
if (m_isMulti) {
// Has been done in notifyEngineRemoteServerRunning
} else {
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));
}
}
startGdb();
}
startGdb();
}
void GdbRemoteServerEngine::notifyEngineRemoteSetupFailed(const QString &reason)
......
......@@ -70,20 +70,25 @@ signals:
* a server start script should be used, but none is given.
*/
void requestSetup();
void aboutToNotifyInferiorSetupOk();
private:
Q_SLOT void readUploadStandardOutput();
Q_SLOT void readUploadStandardError();
Q_SLOT void uploadProcError(QProcess::ProcessError error);
Q_SLOT void uploadProcFinished();
Q_SLOT void callTargetRemote();
virtual void notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort);
virtual void notifyEngineRemoteSetupFailed(const QString &reason);
void notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort);
void notifyEngineRemoteSetupFailed(const QString &reason);
void notifyEngineRemoteServerRunning(const QByteArray &serverChannel, int inferiorPid);
void notifyInferiorSetupOk();
void handleSetTargetAsync(const GdbResponse &response);
void handleFileExecAndSymbols(const GdbResponse &response);
void callTargetRemote();
void handleTargetRemote(const GdbResponse &response);
void handleTargetExtendedRemote(const GdbResponse &response);
void handleTargetExtendedAttach(const GdbResponse &response);
void handleTargetQnx(const GdbResponse &response);
void handleAttach(const GdbResponse &response);
void handleInterruptInferior(const GdbResponse &response);
......@@ -91,6 +96,9 @@ private:
QProcess m_uploadProc;
LocalGdbProcess m_gdbProc;
bool m_isMulti;
int m_targetPid;
QByteArray m_serverChannel;
};
} // namespace Internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment