NSAutoreleasePool 中的 sysctl ->总线错误&段错误
预先感谢所有试图帮助我的人。我在这里遇到了一个大问题,我找到了一些有关 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
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 whetherbuf
is allocated or is pointing to some random memory location.我的预感是这与您滥用
strncpy()
有关。您正在复制sdl->sdl_nlen
个字符。如果该值大于 32,则说明缓冲区溢出。如果正好是 32,则您对\0
的分配位于s[]
之外(可能在buf
中)。无论哪种情况,您都会将某种非法内存传递给
NSLog()
,它本身会生成自动释放的变量。泳池排水时发生的事故很可能是其中之一造成的。My hunch is it's to do with your misuse of
strncpy()
. You're copyingsdl->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 ofs[]
(likely inbuf
).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.