forked from qt-creator/qt-creator
Add support for the remote QNX debugging protocol
Change-Id: Ifb2a378cdc000eb84b65f25c2132783d3a3f53c4 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -110,6 +110,7 @@ public:
|
|||||||
bool useServerStartScript;
|
bool useServerStartScript;
|
||||||
QString serverStartScript;
|
QString serverStartScript;
|
||||||
QString sysroot;
|
QString sysroot;
|
||||||
|
QString searchPath; // Gdb "set solib-search-path"
|
||||||
QString debugInfoLocation; // Gdb "set-debug-file-directory".
|
QString debugInfoLocation; // Gdb "set-debug-file-directory".
|
||||||
QStringList debugSourceLocation; // Gdb "directory"
|
QStringList debugSourceLocation; // Gdb "directory"
|
||||||
QByteArray remoteDumperLib;
|
QByteArray remoteDumperLib;
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
|
|||||||
m_gdbVersion = 100;
|
m_gdbVersion = 100;
|
||||||
m_gdbBuildVersion = -1;
|
m_gdbBuildVersion = -1;
|
||||||
m_isMacGdb = false;
|
m_isMacGdb = false;
|
||||||
|
m_isQnxGdb = false;
|
||||||
m_hasBreakpointNotifications = false;
|
m_hasBreakpointNotifications = false;
|
||||||
m_hasPython = false;
|
m_hasPython = false;
|
||||||
m_registerNamesListed = false;
|
m_registerNamesListed = false;
|
||||||
@@ -1689,9 +1690,10 @@ void GdbEngine::handleShowVersion(const GdbResponse &response)
|
|||||||
m_gdbVersion = 100;
|
m_gdbVersion = 100;
|
||||||
m_gdbBuildVersion = -1;
|
m_gdbBuildVersion = -1;
|
||||||
m_isMacGdb = false;
|
m_isMacGdb = false;
|
||||||
|
m_isQnxGdb = false;
|
||||||
QString msg = QString::fromLocal8Bit(response.consoleStreamOutput);
|
QString msg = QString::fromLocal8Bit(response.consoleStreamOutput);
|
||||||
extractGdbVersion(msg,
|
extractGdbVersion(msg,
|
||||||
&m_gdbVersion, &m_gdbBuildVersion, &m_isMacGdb);
|
&m_gdbVersion, &m_gdbBuildVersion, &m_isMacGdb, &m_isQnxGdb);
|
||||||
|
|
||||||
// On Mac, fsf gdb does not work sufficiently well,
|
// On Mac, fsf gdb does not work sufficiently well,
|
||||||
// and on Linux and Windows we require at least 7.2.
|
// and on Linux and Windows we require at least 7.2.
|
||||||
|
|||||||
@@ -438,6 +438,7 @@ private: ////////// Gdb Output, State & Capability Handling //////////
|
|||||||
int m_gdbVersion; // 6.8.0 is 60800
|
int m_gdbVersion; // 6.8.0 is 60800
|
||||||
int m_gdbBuildVersion; // MAC only?
|
int m_gdbBuildVersion; // MAC only?
|
||||||
bool m_isMacGdb;
|
bool m_isMacGdb;
|
||||||
|
bool m_isQnxGdb;
|
||||||
bool m_hasBreakpointNotifications;
|
bool m_hasBreakpointNotifications;
|
||||||
bool m_hasPython;
|
bool m_hasPython;
|
||||||
bool m_hasInferiorThreadList;
|
bool m_hasInferiorThreadList;
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ QByteArray GdbResponse::toString() const
|
|||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void extractGdbVersion(const QString &msg,
|
void extractGdbVersion(const QString &msg,
|
||||||
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb)
|
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb, bool *isQnxGdb)
|
||||||
{
|
{
|
||||||
const QChar dot(QLatin1Char('.'));
|
const QChar dot(QLatin1Char('.'));
|
||||||
|
|
||||||
@@ -433,6 +433,7 @@ void extractGdbVersion(const QString &msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*isMacGdb = msg.contains(QLatin1String("Apple version"));
|
*isMacGdb = msg.contains(QLatin1String("Apple version"));
|
||||||
|
*isQnxGdb = msg.contains(QLatin1String("qnx-nto"));
|
||||||
|
|
||||||
*gdbVersion = 10000 * cleaned.section(dot, 0, 0).toInt()
|
*gdbVersion = 10000 * cleaned.section(dot, 0, 0).toInt()
|
||||||
+ 100 * cleaned.section(dot, 1, 1).toInt()
|
+ 100 * cleaned.section(dot, 1, 1).toInt()
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void extractGdbVersion(const QString &msg,
|
void extractGdbVersion(const QString &msg,
|
||||||
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb);
|
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb, bool *isQnxGdb);
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ void RemoteGdbServerAdapter::setupInferior()
|
|||||||
const QByteArray sysroot = sp.sysroot.toLocal8Bit();
|
const QByteArray sysroot = sp.sysroot.toLocal8Bit();
|
||||||
const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
|
const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
|
||||||
const QByteArray gnuTarget = sp.gnuTarget.toLatin1();
|
const QByteArray gnuTarget = sp.gnuTarget.toLatin1();
|
||||||
|
const QByteArray searchPath = startParameters().searchPath.toLocal8Bit();
|
||||||
const QString args = sp.processArgs;
|
const QString args = sp.processArgs;
|
||||||
|
|
||||||
if (!remoteArch.isEmpty())
|
if (!remoteArch.isEmpty())
|
||||||
@@ -181,6 +182,8 @@ void RemoteGdbServerAdapter::setupInferior()
|
|||||||
m_engine->postCommand("set gnutarget " + gnuTarget);
|
m_engine->postCommand("set gnutarget " + gnuTarget);
|
||||||
if (!sysroot.isEmpty())
|
if (!sysroot.isEmpty())
|
||||||
m_engine->postCommand("set sysroot " + sysroot);
|
m_engine->postCommand("set sysroot " + sysroot);
|
||||||
|
if (!searchPath.isEmpty())
|
||||||
|
m_engine->postCommand("set solib-search-path " + searchPath);
|
||||||
if (!args.isEmpty())
|
if (!args.isEmpty())
|
||||||
m_engine->postCommand("-exec-arguments " + args.toLocal8Bit());
|
m_engine->postCommand("-exec-arguments " + args.toLocal8Bit());
|
||||||
|
|
||||||
@@ -245,8 +248,13 @@ void RemoteGdbServerAdapter::callTargetRemote()
|
|||||||
// (2) starts the remote application
|
// (2) starts the remote application
|
||||||
// (3) stops the remote application (early, e.g. in the dynamic linker)
|
// (3) stops the remote application (early, e.g. in the dynamic linker)
|
||||||
QString channel = startParameters().remoteChannel;
|
QString channel = startParameters().remoteChannel;
|
||||||
|
if (m_engine->m_isQnxGdb) {
|
||||||
|
m_engine->postCommand("target qnx " + channel.toLatin1(),
|
||||||
|
CB(handleTargetQnx));
|
||||||
|
} else {
|
||||||
m_engine->postCommand("target remote " + channel.toLatin1(),
|
m_engine->postCommand("target remote " + channel.toLatin1(),
|
||||||
CB(handleTargetRemote));
|
CB(handleTargetRemote));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
|
void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
|
||||||
@@ -265,6 +273,52 @@ void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteGdbServerAdapter::handleTargetQnx(const GdbResponse &response)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_engine->m_isQnxGdb, qDebug() << m_engine->m_isQnxGdb);
|
||||||
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||||
|
if (response.resultClass == GdbResultDone) {
|
||||||
|
// gdb server will stop the remote application itself.
|
||||||
|
showMessage(_("INFERIOR STARTED"));
|
||||||
|
showMessage(msgAttachedToStoppedInferior(), StatusBar);
|
||||||
|
|
||||||
|
const qint64 pid = startParameters().attachPID;
|
||||||
|
if (pid > -1) {
|
||||||
|
m_engine->postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
|
||||||
|
} else {
|
||||||
|
m_engine->handleInferiorPrepared();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 16^error,msg="hd:5555: Connection timed out."
|
||||||
|
QString msg = msgConnectRemoteServerFailed(
|
||||||
|
QString::fromLocal8Bit(response.data.findChild("msg").data()));
|
||||||
|
m_engine->notifyInferiorSetupFailed(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteGdbServerAdapter::handleAttach(const GdbResponse &response)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||||
|
switch (response.resultClass) {
|
||||||
|
case GdbResultDone:
|
||||||
|
case GdbResultRunning: {
|
||||||
|
showMessage(_("INFERIOR ATTACHED"));
|
||||||
|
showMessage(msgAttachedToStoppedInferior(), StatusBar);
|
||||||
|
m_engine->handleInferiorPrepared();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GdbResultError:
|
||||||
|
if (response.data.findChild("msg").data() == "ptrace: Operation not permitted.") {
|
||||||
|
m_engine->notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if msg != "ptrace: ..." fall through
|
||||||
|
default:
|
||||||
|
QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data());
|
||||||
|
m_engine->notifyInferiorSetupFailed(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteGdbServerAdapter::runEngine()
|
void RemoteGdbServerAdapter::runEngine()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ private:
|
|||||||
void handleFileExecAndSymbols(const GdbResponse &response);
|
void handleFileExecAndSymbols(const GdbResponse &response);
|
||||||
void callTargetRemote();
|
void callTargetRemote();
|
||||||
void handleTargetRemote(const GdbResponse &response);
|
void handleTargetRemote(const GdbResponse &response);
|
||||||
|
void handleTargetQnx(const GdbResponse &response);
|
||||||
|
void handleAttach(const GdbResponse &response);
|
||||||
void handleInterruptInferior(const GdbResponse &response);
|
void handleInterruptInferior(const GdbResponse &response);
|
||||||
|
|
||||||
QProcess m_uploadProc;
|
QProcess m_uploadProc;
|
||||||
|
|||||||
Reference in New Issue
Block a user