为什么 poll 要求其主要参数在调用之后仍然有效?

发布于 2025-01-08 05:23:34 字数 1170 浏览 0 评论 0原文

我正在我的一个小项目中探索 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 技术交流群。

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

发布评论

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

评论(1

时光匆匆的小流年 2025-01-15 05:23:34

您错误地识别了问题。

const int nbDescriptors = poll(&descriptors, m_fd+1, 10*1000);

这是错误的,因为 poll 的第一个参数是一个(指向)数组,第二个参数是该数组中的元素数量。

结果,系统调用读取到了数组末尾。通过将其声明为static,您只需在内存中移动内容即可,并且很幸运。

您需要:

const int nbDescriptors = poll(&descriptors, 1, 10*1000);

You have misidentified the problem.

const int nbDescriptors = poll(&descriptors, m_fd+1, 10*1000);

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:

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