NSAutoreleasePool 中的 sysctl ->总线错误&段错误

发布于 2024-10-27 05:54:37 字数 1732 浏览 7 评论 0原文

预先感谢所有试图帮助我的人。我在这里遇到了一个大问题,我找到了一些有关 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 );
        }
    }

Thanks in advance to everyone trying to help me. I'm having a big issue here, I've found some example code about sysctl and extended it so I can query the network interfaces for their in/out data. When I run this code directly in main() (without any NSAutoreleasePool) everything works fine. However, once I add it to my class and execute it I get bus errors & segfaults. I've tracked the issue down to NSAutoreleasePools. Can anybody please help? (If you don't believe it, just place a NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; before the code and place the whole thing into 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 );
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘味果▽酱 2024-11-03 05:54:37

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

就您而言,它是未初始化的数据。您没有初始化 alloc 变量。因此,buf 是否被分配或指向某个随机内存位置是完全随机的。

The NSAutoreleasePool isn't the problem. It just reveals that you have a problem with memory allocation, double releases, dangling pointers or uninitialized data.

In your case, it's uninitialized data. You don't initialize the alloc variable. As a consequence, it's completely random whether buf is allocated or is pointing to some random memory location.

昔日梦未散 2024-11-03 05:54:37

我的预感是这与您滥用 strncpy() 有关。您正在复制 sdl->sdl_nlen 个字符。如果该值大于 32,则说明缓冲区溢出。如果正好是 32,则您对 \0 的分配位于 s[] 之外(可能在 buf 中)。

无论哪种情况,您都会将某种非法内存传递给 NSLog(),它本身会生成自动释放的变量。泳池排水时发生的事故很可能是其中之一造成的。

My hunch is it's to do with your misuse of strncpy(). You're copying sdl->sdl_nlen characters. If this is larger than 32, then you're overflowing your buffer. If it's exactly 32, then your assignment of \0 is outside of s[] (likely in buf).

In either case, you're passing some kind of illegal memory to NSLog(), which itself generates autoreleased variables. Likely one of those is responsible for the crash when the pool drains.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文