diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ crashedapplication.cpp debugger.cpp debuggerlaunchers.cpp + queryptrace.cpp debuggermanager.cpp applicationdetailsexamples.cpp gdbhighlighter.cpp diff --git a/src/debuggerlaunchers.h b/src/debuggerlaunchers.h --- a/src/debuggerlaunchers.h +++ b/src/debuggerlaunchers.h @@ -78,14 +78,15 @@ { Q_OBJECT public: - explicit DBusInterfaceLauncher(const QString &name, DBusInterfaceAdaptor *parent = nullptr); + explicit DBusInterfaceLauncher(const QString &name, qint64 pid, DBusInterfaceAdaptor *parent = nullptr); QString name() const override; public Q_SLOTS: void start() override; private: QString m_name; + qint64 m_pid; }; class DBusInterfaceAdaptor : public QDBusAbstractAdaptor @@ -97,7 +98,7 @@ public Q_SLOTS: int pid(); - Q_NOREPLY void registerDebuggingApplication(const QString &name); + Q_NOREPLY void registerDebuggingApplication(const QString &name, qint64 pid = 0); Q_NOREPLY void debuggingFinished(const QString &name); Q_NOREPLY void debuggerClosed(const QString &name); diff --git a/src/debuggerlaunchers.cpp b/src/debuggerlaunchers.cpp --- a/src/debuggerlaunchers.cpp +++ b/src/debuggerlaunchers.cpp @@ -16,6 +16,7 @@ */ #include "debuggerlaunchers.h" +#include #include #include @@ -26,6 +27,8 @@ #include "drkonqi.h" #include "crashedapplication.h" +#include "queryptrace.h" + DefaultDebuggerLauncher::DefaultDebuggerLauncher(const Debugger & debugger, DebuggerManager *parent) : AbstractDebuggerLauncher(parent), m_debugger(debugger) { @@ -51,6 +54,7 @@ emit starting(); int pid = KProcess::startDetached(KShell::splitArgs(str)); if ( pid > 0 ) { + queryPtrace(pid); m_monitor->startMonitoring(pid); } else { qCWarning(DRKONQI_LOG) << "Could not start debugger:" << name(); @@ -60,6 +64,7 @@ void DefaultDebuggerLauncher::onProcessFinished() { + queryPtrace(QCoreApplication::applicationPid()); emit finished(); } @@ -76,8 +81,8 @@ #endif -DBusInterfaceLauncher::DBusInterfaceLauncher(const QString &name, DBusInterfaceAdaptor *parent) - : AbstractDebuggerLauncher(parent), m_name(name) +DBusInterfaceLauncher::DBusInterfaceLauncher(const QString &name, qint64 pid, DBusInterfaceAdaptor *parent) + : AbstractDebuggerLauncher(parent), m_name(name), m_pid(pid) { } @@ -89,6 +94,9 @@ void DBusInterfaceLauncher::start() { emit starting(); + + queryPtrace(m_pid); + emit static_cast(parent())->acceptDebuggingApplication(m_name); } @@ -108,10 +116,10 @@ return DrKonqi::crashedApplication()->pid(); } -void DBusInterfaceAdaptor::registerDebuggingApplication(const QString &name) +void DBusInterfaceAdaptor::registerDebuggingApplication(const QString &name, qint64 pid) { if (!name.isEmpty() && !m_launchers.contains(name)) { - auto launcher = new DBusInterfaceLauncher(name, this); + auto launcher = new DBusInterfaceLauncher(name, pid, this); m_launchers.insert(name, launcher); static_cast(parent())->addDebugger(launcher, true); } @@ -121,6 +129,7 @@ { auto it = m_launchers.find(name); if (it != m_launchers.end()) { + queryPtrace(QCoreApplication::applicationPid()); emit it.value()->finished(); } } diff --git a/src/queryptrace.h b/src/queryptrace.h new file mode 100644 --- /dev/null +++ b/src/queryptrace.h @@ -0,0 +1,10 @@ +#ifndef QUERYPTRACE_H +#define QUERYPTRACE_H + +#ifdef Q_OS_LINUX +void queryPtrace(long long pid); +#else +#define queryPtrace(x) +#endif + +#endif diff --git a/src/queryptrace.cpp b/src/queryptrace.cpp new file mode 100644 --- /dev/null +++ b/src/queryptrace.cpp @@ -0,0 +1,49 @@ +#include + +#ifdef Q_OS_LINUX + +#include "drkonqi_debug.h" + +#include +#include +#include +#include +#include + +#include +#include + +void queryPtrace(long long pid) +{ + struct sockaddr_un server; + socklen_t sl = sizeof(server); + + int sfd = socket(PF_UNIX, SOCK_STREAM, 0); + if (sfd < 0) + return; + + server.sun_family = AF_UNIX; + sprintf(server.sun_path, "kcrash_%lld", QCoreApplication::applicationPid()); + if (::connect(sfd, (struct sockaddr *)&server, sl) == 0) { + char msg[22]; + sprintf(msg, "%lld", pid); + if (write(sfd, msg, 22) > 0) { + fd_set set; + FD_ZERO(&set); + FD_SET(sfd, &set); + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + if (select(sfd + 1, &set, NULL, NULL, &timeout) > 0 && + read(sfd, msg, 3) > 0 && strcmp(msg, "OK") == 0) { + qCInfo(DRKONQI_LOG) << "ptrace granted by debugged process"; + } + } + } + + close(sfd); +} + +#endif diff --git a/src/tests/crashtest/crashtest.cpp b/src/tests/crashtest/crashtest.cpp --- a/src/tests/crashtest/crashtest.cpp +++ b/src/tests/crashtest/crashtest.cpp @@ -135,11 +135,8 @@ parser.process(app); aboutData.processCommandLine(&parser); - //start drkonqi directly so that drkonqi's output goes to the console - KCrash::CrashFlags flags = KCrash::AlwaysDirectly; if (parser.isSet(QStringLiteral("autorestart"))) - flags |= KCrash::AutoRestart; - KCrash::setFlags(flags); + KCrash::setFlags(KCrash::AutoRestart); QByteArray type = parser.positionalArguments().isEmpty() ? QByteArray() : parser.positionalArguments().first().toUtf8(); int crashtype = Crash;