【问题标题】:macOS: DNSSD crash after calling fd_set on its socketmacOS:在其套接字上调用 fd_set 后 DNSSD 崩溃
【发布时间】:2021-06-29 08:23:30
【问题描述】:

我有以下代码,它在调用 FD_SET 时使我的程序崩溃。

void handleEvents(DNSServiceRef service, const int32_t timeout)
{
    if (!service)
      return;

    const int fd = DNSServiceRefSockFD( service );
    const int nfds = fd + 1;

    if (fd < 0)
      return;

    int32_t result = servus::Result::PENDING;
    while(result == servus::Result::PENDING)
    {
        fd_set fdSet;
        FD_ZERO( &fdSet );
        FD_SET( fd, &fdSet ); /// < The crash occurs here

        const int result = ::select( nfds, &fdSet, 0, 0, 0);
        switch (result)
        {
          case 0: // timeout
            return;

          case -1: // error
            std::cerr << "Select error: " << strerror( errno ) << " (" << errno
                 << ")" << std::endl;
            if( errno != EINTR )
            {
                withdraw();
                return;
            }
            break;

          default:
            if(FD_ISSET( fd, &fdSet ))
            {
                const auto error = DNSServiceProcessResult(service);

                if(error != kDNSServiceErr_NoError)
                {
                    std::cerr << "DNSServiceProcessResult error: " << error << std::endl;
                    withdraw();
                    return;
                }
            }
            break;
        }
    }
}

崩溃日志是:

Exception Type:        EXC_GUARD
Exception Codes:       0x6000000000000012, 0x0000000000000002
Exception Note:        EXC_CORPSE_NOTIFY

Termination Reason:    LIBSYSTEM, [0x2]

External Modification Warnings:
Debugger attached to process.

Thread 0 Crashed:
0   libsystem_kernel.dylib          0x00007fff6d62d96e os_fault_with_payload + 10
1   libsystem_kernel.dylib          0x00007fff6d62e451 __darwin_check_fd_set_overflow.cold.2 + 31
2   libsystem_kernel.dylib          0x00007fff6d61967c __darwin_check_fd_set_overflow + 68
3   score                           0x00000001004f097e handleEvents(_DNSServiceRef_t*, int) + 302

我真的不明白哪里出了问题——导致崩溃的“关键链”似乎是

const int fd = DNSServiceRefSockFD( service );
const int nfds = fd + 1;
int result = 0;

fd_set fdSet;
FD_ZERO( &fdSet );
FD_SET( fd, &fdSet ); /// < The crash occurs here

result = ::select( nfds, &fdSet, 0, 0, 0);
fd_set fdSet;
FD_ZERO( &fdSet );
FD_SET( fd, &fdSet ); /// < or here

【问题讨论】:

    标签: c++ macos bonjour dns-sd


    【解决方案1】:

    这种情况下的实际问题是我打开了太多文件描述符,这可以通过使用以下代码增加 rlimit 来解决:

    void setup_min_fd(int min_fds)
    {
      struct rlimit rlim;
      if (getrlimit(RLIMIT_NOFILE, &rlim) != 0)
        return;
    
      if (rlim.rlim_cur > rlim_t(min_fds))
        return;
    
      rlim.rlim_cur = rlim.min_fds;
    
      setrlimit(RLIMIT_NOFILE, &rlim);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-09
      • 2018-09-04
      • 2020-02-07
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      相关资源
      最近更新 更多