Commit 2c0f0449 authored by Christoph Roick's avatar Christoph Roick
Browse files

DrKonqi: Enable DBus-Interface for debugging with KDevelop

Summary:
- register a DBus service to make it work at all
- service name unique by debuggee pid
- switch hierarchy of adaptor and launcher
  - a single adaptor keeps track of multiple launchers
  - the debugger should provide a unique identification
- only works with a corresponding patch in KDevelop

Test Plan:
- apply KDevelop patch D10196 and start a new KDevelop session "test"
- enable the DrKonqi debug button
- enable ptrace
- start a kde program (kate for instance)
- start "drkonqi --dialog --appname kate --pid xxxx"
- check Debug options: gdb, KDevelop (GDB) - test, KDevelop (LLDB) - test
- start another KDevelop session "test2" -> additional debug options are now available
- end session "test2" -> additional options vanished again
- select "KDevelop (GDB) - test" -> KDevelop raises, DrKonqi buttons are disabled
- use the GDB console to detach the process and end GDB
- DrKonqi buttons are reenabled again

Reviewers: #kdevelop, #plasma_workspaces, mwolff

Reviewed By: #kdevelop, mwolff

Subscribers: mwolff, ngraham, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D10195
parent b974c140
......@@ -76,42 +76,59 @@ void TerminalDebuggerLauncher::start()
#endif
DBusOldInterfaceLauncher::DBusOldInterfaceLauncher(DebuggerManager *parent)
: AbstractDebuggerLauncher(parent)
DBusInterfaceLauncher::DBusInterfaceLauncher(const QString &name, DBusInterfaceAdaptor *parent)
: AbstractDebuggerLauncher(parent), m_name(name)
{
m_adaptor = new DBusOldInterfaceAdaptor(this);
QDBusConnection::sessionBus().registerObject(QStringLiteral("/krashinfo"), this);
}
QString DBusOldInterfaceLauncher::name() const
QString DBusInterfaceLauncher::name() const
{
return m_name;
}
void DBusOldInterfaceLauncher::start()
void DBusInterfaceLauncher::start()
{
emit starting();
emit m_adaptor->acceptDebuggingApplication();
emit static_cast<DBusInterfaceAdaptor*>(parent())->acceptDebuggingApplication(m_name);
}
DBusOldInterfaceAdaptor::DBusOldInterfaceAdaptor(DBusOldInterfaceLauncher *parent)
DBusInterfaceAdaptor::DBusInterfaceAdaptor(DebuggerManager *parent)
: QDBusAbstractAdaptor(parent)
{
Q_ASSERT(parent);
if (QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.drkonqi-%1").arg(pid()))) {
QDBusConnection::sessionBus().registerObject(QStringLiteral("/debugger"), parent);
}
}
int DBusOldInterfaceAdaptor::pid()
int DBusInterfaceAdaptor::pid()
{
return DrKonqi::crashedApplication()->pid();
}
void DBusOldInterfaceAdaptor::registerDebuggingApplication(const QString & name)
void DBusInterfaceAdaptor::registerDebuggingApplication(const QString &name)
{
if ( static_cast<DBusOldInterfaceLauncher*>(parent())->m_name.isEmpty() && !name.isEmpty() ) {
static_cast<DBusOldInterfaceLauncher*>(parent())->m_name = name;
emit static_cast<DBusOldInterfaceLauncher*>(parent())->available();
if (!name.isEmpty() && !m_launchers.contains(name)) {
auto launcher = new DBusInterfaceLauncher(name, this);
m_launchers.insert(name, launcher);
static_cast<DebuggerManager*>(parent())->addDebugger(launcher, true);
}
}
void DBusInterfaceAdaptor::debuggingFinished(const QString &name)
{
auto it = m_launchers.find(name);
if (it != m_launchers.end()) {
emit it.value()->finished();
}
}
void DBusInterfaceAdaptor::debuggerClosed(const QString &name)
{
auto it = m_launchers.find(name);
if (it != m_launchers.end()) {
emit it.value()->invalidated();
}
}
......@@ -29,7 +29,7 @@ class AbstractDebuggerLauncher : public QObject
Q_OBJECT
Q_PROPERTY(QString name READ name)
public:
explicit AbstractDebuggerLauncher(DebuggerManager *parent = nullptr) : QObject(parent) {}
explicit AbstractDebuggerLauncher(QObject *parent = nullptr) : QObject(parent) {}
virtual QString name() const = 0;
public Q_SLOTS:
......@@ -71,42 +71,41 @@ public slots:
};
#endif
class DBusOldInterfaceAdaptor;
class DBusInterfaceAdaptor;
/** This class handles the old drkonqi dbus interface used by kdevelop */
class DBusOldInterfaceLauncher : public AbstractDebuggerLauncher
class DBusInterfaceLauncher : public AbstractDebuggerLauncher
{
Q_OBJECT
friend class DBusOldInterfaceAdaptor;
public:
explicit DBusOldInterfaceLauncher(DebuggerManager *parent = nullptr);
explicit DBusInterfaceLauncher(const QString &name, DBusInterfaceAdaptor *parent = nullptr);
QString name() const override;
public Q_SLOTS:
void start() override;
Q_SIGNALS:
void available();
private:
QString m_name;
DBusOldInterfaceAdaptor *m_adaptor;
};
class DBusOldInterfaceAdaptor : public QDBusAbstractAdaptor
class DBusInterfaceAdaptor : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.Krash")
friend class DBusOldInterfaceLauncher;
Q_CLASSINFO("D-Bus Interface", "org.kde.drkonqi")
public:
explicit DBusOldInterfaceAdaptor(DBusOldInterfaceLauncher *parent);
explicit DBusInterfaceAdaptor(DebuggerManager *parent);
public Q_SLOTS:
int pid();
Q_NOREPLY void registerDebuggingApplication(const QString & name);
Q_NOREPLY void registerDebuggingApplication(const QString &name);
Q_NOREPLY void debuggingFinished(const QString &name);
Q_NOREPLY void debuggerClosed(const QString &name);
Q_SIGNALS:
void acceptDebuggingApplication();
void acceptDebuggingApplication(const QString &name);
private:
QHash<QString, DBusInterfaceLauncher*> m_launchers;
};
#endif // DEBUGGERLAUNCHERS_H
......@@ -27,7 +27,7 @@ struct DebuggerManager::Private
BacktraceGenerator *btGenerator;
bool debuggerRunning;
QList<AbstractDebuggerLauncher*> externalDebuggers;
DBusOldInterfaceLauncher *dbusOldInterfaceLauncher;
DBusInterfaceAdaptor *dbusInterfaceAdaptor;
};
DebuggerManager::DebuggerManager(const Debugger & internalDebugger,
......@@ -44,18 +44,13 @@ DebuggerManager::DebuggerManager(const Debugger & internalDebugger,
foreach(const Debugger & debugger, externalDebuggers) {
if (debugger.isInstalled()) {
AbstractDebuggerLauncher *l = new DefaultDebuggerLauncher(debugger, this); //FIXME
d->externalDebuggers.append(l);
connect(l, &AbstractDebuggerLauncher::starting, this, &DebuggerManager::onDebuggerStarting);
connect(l, &AbstractDebuggerLauncher::finished, this, &DebuggerManager::onDebuggerFinished);
connect(l, &AbstractDebuggerLauncher::invalidated, this, &DebuggerManager::onDebuggerInvalidated);
// TODO: use TerminalDebuggerLauncher instead
addDebugger(new DefaultDebuggerLauncher(debugger, this));
}
}
//setup kdevelop compatibility
d->dbusOldInterfaceLauncher = new DBusOldInterfaceLauncher(this);
connect(d->dbusOldInterfaceLauncher, &DBusOldInterfaceLauncher::starting, this, &DebuggerManager::onDebuggerStarting);
connect(d->dbusOldInterfaceLauncher, &DBusOldInterfaceLauncher::available, this, &DebuggerManager::onDBusOldInterfaceDebuggerAvailable);
d->dbusInterfaceAdaptor = new DBusInterfaceAdaptor(this);
}
DebuggerManager::~DebuggerManager()
......@@ -90,6 +85,17 @@ BacktraceGenerator* DebuggerManager::backtraceGenerator() const
return d->btGenerator;
}
void DebuggerManager::addDebugger(AbstractDebuggerLauncher *launcher, bool emitsignal)
{
d->externalDebuggers.append(launcher);
connect(launcher, &DBusInterfaceLauncher::starting, this, &DebuggerManager::onDebuggerStarting);
connect(launcher, &DBusInterfaceLauncher::finished, this, &DebuggerManager::onDebuggerFinished);
connect(launcher, &AbstractDebuggerLauncher::invalidated, this, &DebuggerManager::onDebuggerInvalidated);
if (emitsignal) {
emit externalDebuggerAdded(launcher);
}
}
void DebuggerManager::onDebuggerStarting()
{
d->debuggerRunning = true;
......@@ -113,11 +119,3 @@ void DebuggerManager::onDebuggerInvalidated()
d->externalDebuggers.removeAt(index);
emit externalDebuggerRemoved(launcher);
}
void DebuggerManager::onDBusOldInterfaceDebuggerAvailable()
{
d->externalDebuggers.append(d->dbusOldInterfaceLauncher);
emit externalDebuggerAdded(d->dbusOldInterfaceLauncher);
}
......@@ -36,6 +36,7 @@ public:
bool showExternalDebuggers() const;
QList<AbstractDebuggerLauncher*> availableExternalDebuggers() const;
BacktraceGenerator *backtraceGenerator() const;
void addDebugger(AbstractDebuggerLauncher *launcher, bool emitsignal = false);
Q_SIGNALS:
void debuggerStarting();
......@@ -48,7 +49,6 @@ private Q_SLOTS:
void onDebuggerStarting();
void onDebuggerFinished();
void onDebuggerInvalidated();
void onDBusOldInterfaceDebuggerAvailable();
private:
struct Private;
......
Supports Markdown
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