1 /*
2 SPDX-FileCopyrightText: 2019 Christoph Roick <chrisito@gmx.de>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 #include "ptracer.h"
7
8 #ifdef Q_OS_LINUX
9
10 #include "drkonqi_debug.h"
11
12 #include <QFile>
13 #include <QStandardPaths>
14
15 #include <sys/poll.h>
16 #include <sys/socket.h>
17 #include <sys/un.h>
18
19 #include <errno.h>
20 #include <unistd.h>
21
setPtracer(qint64 debuggerpid,qint64 debuggeepid)22 void setPtracer(qint64 debuggerpid, qint64 debuggeepid)
23 {
24 int sfd = socket(PF_UNIX, SOCK_STREAM, 0);
25 if (sfd < 0) {
26 qCWarning(DRKONQI_LOG) << "socket to set ptracer not accessible";
27 return;
28 }
29
30 static struct sockaddr_un server;
31 static socklen_t sl = sizeof(server);
32 server.sun_family = AF_UNIX;
33 const QString socketPath = QStringLiteral("%1/kcrash_%2").arg(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation)).arg(debuggeepid);
34
35 if (socketPath.size() >= static_cast<int>(sizeof(server.sun_path))) {
36 qCWarning(DRKONQI_LOG) << "socket path is too long";
37 close(sfd);
38 return;
39 }
40 strcpy(server.sun_path, QFile::encodeName(socketPath).constData());
41
42 if (::connect(sfd, (struct sockaddr *)&server, sl) == 0) {
43 static const int msize = 21; // most digits in a 64bit int (+sign +'\0')
44 char msg[msize];
45 sprintf(msg, "%lld", debuggerpid);
46
47 int r, bytes = 0;
48 while (bytes < msize) {
49 r = write(sfd, msg + bytes, msize - bytes);
50 if (r > 0)
51 bytes += r;
52 else if (r == -1 && errno != EINTR)
53 break;
54 }
55 if (bytes == msize) {
56 struct pollfd fd;
57 fd.fd = sfd;
58 fd.events = POLLIN;
59 while ((r = poll(&fd, 1, 1000)) == -1 && errno == EINTR) { }
60 if (r > 0 && (fd.revents & POLLIN)) {
61 char rmsg[msize];
62 bytes = 0;
63 while (bytes < msize) {
64 r = read(sfd, rmsg + bytes, msize - bytes);
65 if (r > 0)
66 bytes += r;
67 else if (r == -1 && errno != EINTR)
68 break;
69 }
70 if (bytes == msize && memcmp(msg, rmsg, msize) == 0)
71 qCInfo(DRKONQI_LOG) << "ptracer set to" << debuggerpid << "by debugged process";
72 else
73 qCWarning(DRKONQI_LOG) << "debugged process did not acknowledge setting ptracer to" << debuggerpid;
74 close(sfd);
75 return;
76 }
77 }
78 }
79
80 qCWarning(DRKONQI_LOG) << "unable to set ptracer to" << debuggerpid;
81 close(sfd);
82 }
83
84 #else
85
setPtracer(qint64,qint64)86 void setPtracer(qint64, qint64)
87 {
88 }
89
90 #endif
91