【发布时间】:2022-01-11 12:08:53
【问题描述】:
在我的程序中,我有一个线程必须持续监控网络接口,因此它在 while 循环中不断使用 getifaddrs()。
while(true) {
struct ifaddrs *ifaddr, *ifa;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs couldn't fetch required data");
exit(EXIT_FAILURE);
}
//Iterate through interfaces linked list
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
//monitoring logic
}
//Free linked list
freeifaddrs(ifaddr);
//Sleep for specified time fo next polling cycle
usleep(1000);
}
大多数时候我的程序运行良好。但是,有时 getifaddrs() 返回 -1 并且 errNo = EBADF(bad file descriptor)。为了不退出我的线程,我暂时用 continue 替换了 exit(因为我不希望我的程序因此而结束)。但是,我很想知道在哪些情况下 getifaddrs() 会返回“错误文件描述符”错误,以及我是否可以采取一些措施避免这种情况发生?
编辑
用“继续”替换“退出”并没有解决我的问题。有时调用 getifaddrs() 会使应用程序崩溃!
下面给出的是使用生成的核心文件从 gdb 获得的回溯。
Program terminated with signal 6, Aborted.
#0 0x00007fe2df1ef387 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.1.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 krb5-libs-1.15.1-37.el7_6.x86_64 libcom_err-1.42.9-16.el7.x86_64 libgcc-4.8.5-39.el7.x86_64 libselinux-2.5-14.1.el7.x86_64 libstdc++-4.8.5-39.el7.x86_64 openssl-libs-1.0.2k-19.el7.x86_64 pcre-8.32-17.el7.x86_64 zlib-1.2.7-18.el7.x86_64
(gdb) bt
#0 0x00007fe2df1ef387 in raise () from /lib64/libc.so.6
#1 0x00007fe2df1f0a78 in abort () from /lib64/libc.so.6
#2 0x00007fe2df231ed7 in __libc_message () from /lib64/libc.so.6
#3 0x00007fe2df231fbe in __libc_fatal () from /lib64/libc.so.6
#4 0x00007fe2df2df4c2 in __netlink_assert_response () from /lib64/libc.so.6
#5 0x00007fe2df2dc412 in __netlink_request () from /lib64/libc.so.6
#6 0x00007fe2df2dc5ef in getifaddrs_internal () from /lib64/libc.so.6
#7 0x00007fe2df2dd310 in getifaddrs () from /lib64/libc.so.6
#8 0x000000000047c03c in __interceptor_getifaddrs.part.0 ()
操作系统:Red Hat Enterprise Linux Server 7.8 版(迈坡)
GLIBC 版本:2.17
【问题讨论】:
-
引用手册页man7.org/linux/man-pages/man3/getifaddrs.3.html:getifaddrs() 可能会失败并为 socket(2)、bind(2)、getsockname(2)、recvmsg( 2)、sendto(2)、malloc(3) 或 realloc(3)。 其中一些函数将
EBADF指定为可能的errno值。您可以尝试使用系统调用跟踪 (strace) 重现错误。这应该显示哪个系统调用失败并且可能有助于分析问题的原因。 -
或者你在“监控逻辑”中搞砸了
ifaddr内容? -
查看此链接。它可以帮助您确定崩溃的原因。 patchwork.ozlabs.org/project/netdev/patch/…
-
所以......你设置了一个赏金来“吸引更多关注这个问题”然后简单地忽略所有答案并尝试提供帮助? @RainerKeller 提供了一个非常有趣的解决方案,我很想知道它是否对您有所帮助。
-
毫无疑问@RainerKeller 的回答推动了我们的调查......但他自己提到他并没有真正回答核心问题......这就是为什么我还没有奖励赏金,希望可能会有更多回应。