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();
You have misidentified the problem.
This is wrong because the first argument to
pollis 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
staticyou just moved things around in memory and got lucky.You need: