folly icon indicating copy to clipboard operation
folly copied to clipboard

EventBaseAtomicNotificationQueue NotifyFd function crashes on android system

Open stevezhou6 opened this issue 3 years ago • 0 comments

terminating with uncaught exception of type std::__ndk1::system_error: failed to signal AtomicNotificationQueue after write32: Broken pipe

@Robin Cheng @yfeldblum

template <typename Task, typename Consumer>
void EventBaseAtomicNotificationQueue<Task, Consumer>::notifyFd() {
  checkPid();

  ssize_t bytes_written = 0;
  size_t bytes_expected = 0;

  do {
    if (eventfd_ >= 0) {
      // eventfd(2) dictates that we must write a 64-bit integer
      uint64_t signal = 1;
      bytes_expected = sizeof(signal);
      bytes_written = ::write(eventfd_, &signal, bytes_expected);
    } else {
      uint8_t signal = 1;
      bytes_expected = sizeof(signal);
      bytes_written = ::write(pipeFds_[1], &signal, bytes_expected);
    }
  } while (bytes_written == -1 && errno == EINTR);

  if (bytes_written != ssize_t(bytes_expected)) {
    folly::throwSystemError(
        "failed to signal AtomicNotificationQueue after "
        "write",
        errno);
  }
}

I haven't updated to the latest folly yet. I would like to ask whether the following changes have fixed the crash problem above?

  • Unregister event handler fd before closing the fd in EventBaseAtomicNotificationQueue.

Summary: Thread 1:

  • Creates an eventfd X
  • Registers X with an event base
  • Closes X
  • Unregisters X from the event base

Thread 2:

  • Creates some other file descriptor (eventfd or socket or whatever); the operating system reuses file descriptor #X.

The unregistering of X from the event base in thread 1 races with the opening of reused X in thread 2.

The fix is to unregister X before closing X.

Reviewed By: yfeldblum

Differential Revision: D27962155

fbshipit-source-id: 1bcb62c7ebe0297ab9687e1a0edf37d319637fda

stevezhou6 avatar Dec 13 '21 09:12 stevezhou6