我正在我的一个小项目中探索 poll() 函数,我注意到这个片段崩溃了:
ErrorCode XNotifier_Linux::updatePoll()
{
ErrorCode ret = Success;
struct pollfd descriptors = { m_fd, IN_MODIFY, 0 };
const int nbDescriptors = poll(&descriptors, m_fd+1, 10*1000);
if (descriptors.events & (POLLIN | POLLPRI))
ret = DataIsPresent;
return ret;
}
Valgrind 在这里很有用,因为它指出了 unitialized 中的轮询字段 ufds
:
==833== Syscall param poll(ufds.fd) points to uninitialised byte(s)
==833== at 0x569CB28: poll (in /lib64/libc-2.14.1.so)
==833== by 0x400F7A: xnot::XNotifier_Linux::updatePoll() (linux.cpp:72)
==833== by 0x400D4B: xnot::XNotifier_Linux::update() (linux.cpp:28)
==833== by 0x400FF4: main (linux.cpp:90)
==833== Address 0x7fefffbb8 is on thread 1's stack
由于 descriptors
是在堆栈上创建的,我知道当函数返回时,指向 descriptors
的指针不再有效。我认为这个指针可能在函数返回后被使用。为了确认这一点,我将声明描述符的行更改为:static struct pollfd descriptors = { m_fd, IN_MODIFY, 0 };
并且崩溃消失了。
为什么描述符应该比对 poll() 的调用更有效? (或者我哪里搞错了?)
P.-S。 : 描述符由 inotify m_fd = inotify_init();
最佳答案
您错误地识别了问题。
const int nbDescriptors = poll(&descriptors, m_fd+1, 10*1000);
这是错误的,因为 poll
的第一个参数是(指向一个)数组,第二个参数是该数组中元素的数量。
因此,系统调用正在读取数组末尾。通过将其声明为 static
,您只是在内存中移动了一些东西,而且很幸运。
你需要:
const int nbDescriptors = poll(&descriptors, 1, 10*1000);
关于c - 为什么 poll 要求它的 main 参数在调用之后仍然存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9423084/