【问题标题】:sysctl in a NSAutoreleasePool -> bus errors & segfaultsNSAutoreleasePool 中的 sysctl -> 总线错误和段错误
【发布时间】:2011-07-24 00:55:14
【问题描述】:

在此先感谢所有试图帮助我的人。我在这里遇到了一个大问题,我找到了一些关于 sysctl 的示例代码并对其进行了扩展,以便我可以查询网络接口的输入/输出数据。当我直接在 main() 中运行此代码(没有任何 NSAutoreleasePool)时,一切正常。但是,一旦我将它添加到我的班级并执行它,我就会得到总线错误和段错误。我已将问题追溯到 NSAutoreleasePools。有人可以帮忙吗? (如果你不相信,只需在代码前放置一个 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 并将整个东西放入 main())

int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };

    int alloc;

    struct if_msghdr    *ifm, *nextifm;
    struct sockaddr_dl  *sdl;
    char        *lim, *next;
    size_t      needed;
    char        s[32];

    char* buf;
    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
        return 0;

    if (alloc < needed) {
        buf = malloc(needed);
        if (buf == NULL)
            return 0;
        alloc = needed;
    }

    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
        return 0;
    lim = buf + needed;

    next = buf;
    while (next < lim) {
        ifm = (struct if_msghdr *)next;

        if (ifm->ifm_type != RTM_IFINFO)
            return 0;
        next += ifm->ifm_msglen;

        while (next < lim) {
            nextifm = (struct if_msghdr *)next;
            if (nextifm->ifm_type != RTM_NEWADDR)
                break;
            next += nextifm->ifm_msglen;
        }        

        if (ifm != NULL && ifm->ifm_flags & IFF_UP) {
            sdl = (struct sockaddr_dl *)(ifm + 1);
            if (sdl->sdl_family != AF_LINK)
                continue;
            strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
            s[sdl->sdl_nlen] = '\0';
            NSLog(@"interface %s in %qu out %qu \n", s,(UInt64)ifm->ifm_data.ifi_ibytes, (UInt64)ifm->ifm_data.ifi_obytes );
        }
    }

【问题讨论】:

    标签: objective-c nsautoreleasepool sysctl


    【解决方案1】:

    我的预感是这与您滥用 strncpy() 有关。您正在复制 sdl-&gt;sdl_nlen 字符。如果这大于 32,那么你的缓冲区溢出了。如果正好是 32,那么您对 ​​\0 的分配就在 s[] 之外(可能在 buf 中)。

    在任何一种情况下,您都将某种非法内存传递给NSLog(),它本身会生成自动释放的变量。很可能其中一个是造成池耗尽时崩溃的原因。

    【讨论】:

      【解决方案2】:

      NSAutoreleasePool 不是问题所在。它只是表明您在内存分配、双重释放、悬空指针或未初始化数据方面存在问题。

      在您的情况下,它是未初始化的数据。您不初始化 alloc 变量。因此,buf 是否被分配或指向某个随机内存位置是完全随机的。

      【讨论】:

      • 你是完全正确的。那是因为我没有初始化 int alloc。
      • 这就是为什么初始化all你的变量是一个好主意,作为一种习惯。例如,如果 buf 被初始化为 NULL,那么丢失的 alloc 初始化会更容易找到,因为崩溃会更早发生。
      猜你喜欢
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2014-06-10
      • 2012-09-21
      • 2021-04-17
      相关资源
      最近更新 更多