为什么 poll 要求其主要参数在调用之后仍然有效?
我正在我的一个小项目中探索 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 在这里非常有帮助,因为它指出了 poll 字段 ufds
in unialized :
==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
As < code>descriptors 是在堆栈上创建的,我知道当函数返回时,指向 descriptors
的指针不再有效。我想这个指针可能会在函数返回后被使用。为了确认这一点,我将声明描述符的行更改为:static struct pollfd detectors = { m_fd, IN_MODIFY, 0 };
并且崩溃消失了。
为什么描述符的寿命应该比对 poll() 的调用长? (或者是我弄错了什么?)
P.-S. :描述符由 inotify 填充 m_fd = inotify_init();
I’m exploring poll() function on a small project of mine, and I noticed that this snippet crashed:
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 is quite helpful here, because it points out that the poll field ufds
in unitialized :
==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
As descriptors
was created on the stack, I understand that when the function returns, the pointer to descriptors
is no longer valid. I thought that this pointer might be used after the function returns. To confirm that, I changed the line declaring descriptors to : static struct pollfd descriptors = { m_fd, IN_MODIFY, 0 };
and the crash disappeared.
Why should descriptors outlive the call to poll()?
(Or is there something I got wrong?)
P.-S. : the descriptor was filled by inotify m_fd = inotify_init();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您错误地识别了问题。
这是错误的,因为 poll 的第一个参数是一个(指向)数组,第二个参数是该数组中的元素数量。
结果,系统调用读取到了数组末尾。通过将其声明为
static
,您只需在内存中移动内容即可,并且很幸运。您需要:
You have misidentified the problem.
This is wrong because the first argument to
poll
is a (pointer to an) array, and the second argument is the number of elements in that array.As a result, the system call is reading past the end of the array. By declaring it
static
you just moved things around in memory and got lucky.You need: