1 //===-- MainLoopPosix.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Host/posix/MainLoopPosix.h"
10 #include "lldb/Host/Config.h"
11 #include "lldb/Host/PosixApi.h"
12 #include "lldb/Utility/Status.h"
13 #include "llvm/Config/llvm-config.h"
14 #include "llvm/Support/Errno.h"
15 #include <algorithm>
16 #include <cassert>
17 #include <cerrno>
18 #include <csignal>
19 #include <ctime>
20 #include <vector>
21 
22 // Multiplexing is implemented using kqueue on systems that support it (BSD
23 // variants including OSX). On linux we use ppoll, while android uses pselect
24 // (ppoll is present but not implemented properly). On windows we use WSApoll
25 // (which does not support signals).
26 
27 #if HAVE_SYS_EVENT_H
28 #include <sys/event.h>
29 #elif defined(__ANDROID__)
30 #include <sys/syscall.h>
31 #else
32 #include <poll.h>
33 #endif
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 static sig_atomic_t g_signal_flags[NSIG];
39 
SignalHandler(int signo,siginfo_t * info,void *)40 static void SignalHandler(int signo, siginfo_t *info, void *) {
41   assert(signo < NSIG);
42   g_signal_flags[signo] = 1;
43 }
44 
45 class MainLoopPosix::RunImpl {
46 public:
47   RunImpl(MainLoopPosix &loop);
48   ~RunImpl() = default;
49 
50   Status Poll();
51   void ProcessEvents();
52 
53 private:
54   MainLoopPosix &loop;
55 
56 #if HAVE_SYS_EVENT_H
57   std::vector<struct kevent> in_events;
58   struct kevent out_events[4];
59   int num_events = -1;
60 
61 #else
62 #ifdef __ANDROID__
63   fd_set read_fd_set;
64 #else
65   std::vector<struct pollfd> read_fds;
66 #endif
67 
68   sigset_t get_sigmask();
69 #endif
70 };
71 
72 #if HAVE_SYS_EVENT_H
RunImpl(MainLoopPosix & loop)73 MainLoopPosix::RunImpl::RunImpl(MainLoopPosix &loop) : loop(loop) {
74   in_events.reserve(loop.m_read_fds.size());
75 }
76 
Poll()77 Status MainLoopPosix::RunImpl::Poll() {
78   in_events.resize(loop.m_read_fds.size());
79   unsigned i = 0;
80   for (auto &fd : loop.m_read_fds)
81     EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
82 
83   num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
84                       out_events, std::size(out_events), nullptr);
85 
86   if (num_events < 0) {
87     if (errno == EINTR) {
88       // in case of EINTR, let the main loop run one iteration
89       // we need to zero num_events to avoid assertions failing
90       num_events = 0;
91     } else
92       return Status(errno, eErrorTypePOSIX);
93   }
94   return Status();
95 }
96 
ProcessEvents()97 void MainLoopPosix::RunImpl::ProcessEvents() {
98   assert(num_events >= 0);
99   for (int i = 0; i < num_events; ++i) {
100     if (loop.m_terminate_request)
101       return;
102     switch (out_events[i].filter) {
103     case EVFILT_READ:
104       loop.ProcessReadObject(out_events[i].ident);
105       break;
106     case EVFILT_SIGNAL:
107       loop.ProcessSignal(out_events[i].ident);
108       break;
109     default:
110       llvm_unreachable("Unknown event");
111     }
112   }
113 }
114 #else
RunImpl(MainLoopPosix & loop)115 MainLoopPosix::RunImpl::RunImpl(MainLoopPosix &loop) : loop(loop) {
116 #ifndef __ANDROID__
117   read_fds.reserve(loop.m_read_fds.size());
118 #endif
119 }
120 
get_sigmask()121 sigset_t MainLoopPosix::RunImpl::get_sigmask() {
122   sigset_t sigmask;
123   int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask);
124   assert(ret == 0);
125   UNUSED_IF_ASSERT_DISABLED(ret);
126 
127   for (const auto &sig : loop.m_signals)
128     sigdelset(&sigmask, sig.first);
129   return sigmask;
130 }
131 
132 #ifdef __ANDROID__
Poll()133 Status MainLoopPosix::RunImpl::Poll() {
134   // ppoll(2) is not supported on older all android versions. Also, older
135   // versions android (API <= 19) implemented pselect in a non-atomic way, as a
136   // combination of pthread_sigmask and select. This is not sufficient for us,
137   // as we rely on the atomicity to correctly implement signal polling, so we
138   // call the underlying syscall ourselves.
139 
140   FD_ZERO(&read_fd_set);
141   int nfds = 0;
142   for (const auto &fd : loop.m_read_fds) {
143     FD_SET(fd.first, &read_fd_set);
144     nfds = std::max(nfds, fd.first + 1);
145   }
146 
147   union {
148     sigset_t set;
149     uint64_t pad;
150   } kernel_sigset;
151   memset(&kernel_sigset, 0, sizeof(kernel_sigset));
152   kernel_sigset.set = get_sigmask();
153 
154   struct {
155     void *sigset_ptr;
156     size_t sigset_len;
157   } extra_data = {&kernel_sigset, sizeof(kernel_sigset)};
158   if (syscall(__NR_pselect6, nfds, &read_fd_set, nullptr, nullptr, nullptr,
159               &extra_data) == -1) {
160     if (errno != EINTR)
161       return Status(errno, eErrorTypePOSIX);
162     else
163       FD_ZERO(&read_fd_set);
164   }
165 
166   return Status();
167 }
168 #else
Poll()169 Status MainLoopPosix::RunImpl::Poll() {
170   read_fds.clear();
171 
172   sigset_t sigmask = get_sigmask();
173 
174   for (const auto &fd : loop.m_read_fds) {
175     struct pollfd pfd;
176     pfd.fd = fd.first;
177     pfd.events = POLLIN;
178     pfd.revents = 0;
179     read_fds.push_back(pfd);
180   }
181 
182   if (ppoll(read_fds.data(), read_fds.size(), nullptr, &sigmask) == -1 &&
183       errno != EINTR)
184     return Status(errno, eErrorTypePOSIX);
185 
186   return Status();
187 }
188 #endif
189 
ProcessEvents()190 void MainLoopPosix::RunImpl::ProcessEvents() {
191 #ifdef __ANDROID__
192   // Collect first all readable file descriptors into a separate vector and
193   // then iterate over it to invoke callbacks. Iterating directly over
194   // loop.m_read_fds is not possible because the callbacks can modify the
195   // container which could invalidate the iterator.
196   std::vector<IOObject::WaitableHandle> fds;
197   for (const auto &fd : loop.m_read_fds)
198     if (FD_ISSET(fd.first, &read_fd_set))
199       fds.push_back(fd.first);
200 
201   for (const auto &handle : fds) {
202 #else
203   for (const auto &fd : read_fds) {
204     if ((fd.revents & (POLLIN | POLLHUP)) == 0)
205       continue;
206     IOObject::WaitableHandle handle = fd.fd;
207 #endif
208     if (loop.m_terminate_request)
209       return;
210 
211     loop.ProcessReadObject(handle);
212   }
213 
214   std::vector<int> signals;
215   for (const auto &entry : loop.m_signals)
216     if (g_signal_flags[entry.first] != 0)
217       signals.push_back(entry.first);
218 
219   for (const auto &signal : signals) {
220     if (loop.m_terminate_request)
221       return;
222     g_signal_flags[signal] = 0;
223     loop.ProcessSignal(signal);
224   }
225 }
226 #endif
227 
228 MainLoopPosix::MainLoopPosix() : m_triggering(false) {
229   Status error = m_trigger_pipe.CreateNew(/*child_process_inherit=*/false);
230   assert(error.Success());
231   const int trigger_pipe_fd = m_trigger_pipe.GetReadFileDescriptor();
232   m_read_fds.insert({trigger_pipe_fd, [trigger_pipe_fd](MainLoopBase &loop) {
233                        char c;
234                        ssize_t bytes_read = llvm::sys::RetryAfterSignal(
235                            -1, ::read, trigger_pipe_fd, &c, 1);
236                        assert(bytes_read == 1);
237                        UNUSED_IF_ASSERT_DISABLED(bytes_read);
238                        // NB: This implicitly causes another loop iteration
239                        // and therefore the execution of pending callbacks.
240                      }});
241 #if HAVE_SYS_EVENT_H
242   m_kqueue = kqueue();
243   assert(m_kqueue >= 0);
244 #endif
245 }
246 
247 MainLoopPosix::~MainLoopPosix() {
248 #if HAVE_SYS_EVENT_H
249   close(m_kqueue);
250 #endif
251   m_read_fds.erase(m_trigger_pipe.GetReadFileDescriptor());
252   m_trigger_pipe.Close();
253   assert(m_read_fds.size() == 0);
254   assert(m_signals.size() == 0);
255 }
256 
257 MainLoopPosix::ReadHandleUP
258 MainLoopPosix::RegisterReadObject(const IOObjectSP &object_sp,
259                                  const Callback &callback, Status &error) {
260   if (!object_sp || !object_sp->IsValid()) {
261     error.SetErrorString("IO object is not valid.");
262     return nullptr;
263   }
264 
265   const bool inserted =
266       m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second;
267   if (!inserted) {
268     error.SetErrorStringWithFormat("File descriptor %d already monitored.",
269                                    object_sp->GetWaitableHandle());
270     return nullptr;
271   }
272 
273   return CreateReadHandle(object_sp);
274 }
275 
276 // We shall block the signal, then install the signal handler. The signal will
277 // be unblocked in the Run() function to check for signal delivery.
278 MainLoopPosix::SignalHandleUP
279 MainLoopPosix::RegisterSignal(int signo, const Callback &callback,
280                               Status &error) {
281   auto signal_it = m_signals.find(signo);
282   if (signal_it != m_signals.end()) {
283     auto callback_it = signal_it->second.callbacks.insert(
284         signal_it->second.callbacks.end(), callback);
285     return SignalHandleUP(new SignalHandle(*this, signo, callback_it));
286   }
287 
288   SignalInfo info;
289   info.callbacks.push_back(callback);
290   struct sigaction new_action;
291   new_action.sa_sigaction = &SignalHandler;
292   new_action.sa_flags = SA_SIGINFO;
293   sigemptyset(&new_action.sa_mask);
294   sigaddset(&new_action.sa_mask, signo);
295   sigset_t old_set;
296 
297   g_signal_flags[signo] = 0;
298 
299   // Even if using kqueue, the signal handler will still be invoked, so it's
300   // important to replace it with our "benign" handler.
301   int ret = sigaction(signo, &new_action, &info.old_action);
302   UNUSED_IF_ASSERT_DISABLED(ret);
303   assert(ret == 0 && "sigaction failed");
304 
305 #if HAVE_SYS_EVENT_H
306   struct kevent ev;
307   EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
308   ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
309   assert(ret == 0);
310 #endif
311 
312   // If we're using kqueue, the signal needs to be unblocked in order to
313   // receive it. If using pselect/ppoll, we need to block it, and later unblock
314   // it as a part of the system call.
315   ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
316                         &new_action.sa_mask, &old_set);
317   assert(ret == 0 && "pthread_sigmask failed");
318   info.was_blocked = sigismember(&old_set, signo);
319   auto insert_ret = m_signals.insert({signo, info});
320 
321   return SignalHandleUP(new SignalHandle(
322       *this, signo, insert_ret.first->second.callbacks.begin()));
323 }
324 
325 void MainLoopPosix::UnregisterReadObject(IOObject::WaitableHandle handle) {
326   bool erased = m_read_fds.erase(handle);
327   UNUSED_IF_ASSERT_DISABLED(erased);
328   assert(erased);
329 }
330 
331 void MainLoopPosix::UnregisterSignal(
332     int signo, std::list<Callback>::iterator callback_it) {
333   auto it = m_signals.find(signo);
334   assert(it != m_signals.end());
335 
336   it->second.callbacks.erase(callback_it);
337   // Do not remove the signal handler unless all callbacks have been erased.
338   if (!it->second.callbacks.empty())
339     return;
340 
341   sigaction(signo, &it->second.old_action, nullptr);
342 
343   sigset_t set;
344   sigemptyset(&set);
345   sigaddset(&set, signo);
346   int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK,
347                             &set, nullptr);
348   assert(ret == 0);
349   UNUSED_IF_ASSERT_DISABLED(ret);
350 
351 #if HAVE_SYS_EVENT_H
352   struct kevent ev;
353   EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0);
354   ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
355   assert(ret == 0);
356 #endif
357 
358   m_signals.erase(it);
359 }
360 
361 Status MainLoopPosix::Run() {
362   m_terminate_request = false;
363 
364   Status error;
365   RunImpl impl(*this);
366 
367   // run until termination or until we run out of things to listen to
368   // (m_read_fds will always contain m_trigger_pipe fd, so check for > 1)
369   while (!m_terminate_request &&
370          (m_read_fds.size() > 1 || !m_signals.empty())) {
371     error = impl.Poll();
372     if (error.Fail())
373       return error;
374 
375     impl.ProcessEvents();
376 
377     m_triggering = false;
378     ProcessPendingCallbacks();
379   }
380   return Status();
381 }
382 
383 void MainLoopPosix::ProcessReadObject(IOObject::WaitableHandle handle) {
384   auto it = m_read_fds.find(handle);
385   if (it != m_read_fds.end())
386     it->second(*this); // Do the work
387 }
388 
389 void MainLoopPosix::ProcessSignal(int signo) {
390   auto it = m_signals.find(signo);
391   if (it != m_signals.end()) {
392     // The callback may actually register/unregister signal handlers,
393     // so we need to create a copy first.
394     llvm::SmallVector<Callback, 4> callbacks_to_run{
395         it->second.callbacks.begin(), it->second.callbacks.end()};
396     for (auto &x : callbacks_to_run)
397       x(*this); // Do the work
398   }
399 }
400 
401 void MainLoopPosix::TriggerPendingCallbacks() {
402   if (m_triggering.exchange(true))
403     return;
404 
405   char c = '.';
406   size_t bytes_written;
407   Status error = m_trigger_pipe.Write(&c, 1, bytes_written);
408   assert(error.Success());
409   UNUSED_IF_ASSERT_DISABLED(error);
410   assert(bytes_written == 1);
411 }
412