我有一个使用timerfd_create()
创建计时器的程序,并且定时器被指定为一个间隔,以便定期通知进程。然后此计时器注册到epoll
。误差的无效的参数执行时read()
在处理程序,和errno
是22,当我在我的覆盆子PI(Raspbian,Linux的4.9运行此程序,将出现此错误.80),但是当我在笔记本电脑上运行时,一切都很好(Arch,Linux 4.15.15)。
相关代码粘贴在下面。非常感谢任何帮助。
void epset_reg(int epfd, int fd, u32 events)
{
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
ev.data.fd = fd;
ev.events = events;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
handle_err("epoll_ctl");
}
int init_timer(u32 interval)
{
int tfd;
struct itimerspec tspec;
/* specify the timer */
tspec.it_value.tv_sec = 1;
tspec.it_value.tv_nsec = 0;
tspec.it_interval.tv_sec = interval;
tspec.it_interval.tv_nsec = 0;
/* create timerfd */
if ((tfd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0)
handle_err("timerfd_create");
/* arm (start) the periodic timer */
if (timerfd_settime(tfd, TFD_TIMER_ABSTIME, &tspec, NULL) < 0)
handle_err("timerfd_settime");
return tfd;
}
void handler(int tfd)
{
u64 exp;
/* THE ERROR ! */
if (read(tfd, &exp, sizeof(exp)) < 0)
handle_err("read");
/* irrelevant parts */
}
int main()
{
int epfd, tfd, sock, nfds, i;
struct epoll_event events[MAX_EVENTS];
/* create new epoll instance */
if ((epfd = epoll_create1(0)) < 0)
handle_err("epoll_create1");
/* obtain timerfd */
tfd = init_timer(TIMER_INTERVAL);
/* obtain socket to listen */
sock = init_socket(CC_PORT);
/* register sock and tfd to epoll set */
epset_reg(epfd, tfd, EPOLLIN);
epset_reg(epfd, sock, EPOLLIN | EPOLLET);
for (;;) {
if ((nfds = epoll_wait(epfd, events, MAX_EVENTS, -1)) < 0)
handle_err("epoll_wait");
for (i = 0; i < nfds; ++i) {
if ((events[i].events & EPOLLERR) ||
(events[i].events & EPOLLHUP) ||
(!(events[i].events & EPOLLIN))) {
fprintf(stderr, "epoll\n");
close(events[i].data.fd);
continue;
}
if (events[i].data.fd == tfd)
handler(tfd);
else if (events[i].data.fd == sock)
accept_conn(sock, epfd);
else
handle_message(events[i].data.fd);
}
}
}
完整的程序位于https://github.com/iamlazynic/centralized_wlan/tree/master/cc和cc.c内的main.c。
除了有关这个问题的建议外,如果有关于如何在这种情况下进行调试的建议,那将会很棒。谢谢!
答案 0 :(得分:1)
以下是读取功能的概要。
ssize_t read(int fildes,void * buf,size_t nbyte);
第二个是buf指针,第三个是要读取的大小。您将大小设置为64字节。但是指针是在堆栈处分配的exp(8字节)的地址。我认为它可以破坏堆栈。
答案 1 :(得分:1)
完成此操作后,我们发现u64
的typedef错误,代码尝试读取几个字节,这将导致EINVAL
错误代码。 typedef是:
typedef unsigned long int u64;
但是在32位系统上,这可能是4个字节的大小。相反,我们使用了stdint.h和uint64_t
类型(它会为您正在使用的平台更加谨慎地键入dede)并且现在具有正确的大小。