2011-07-25 61 views
1

我正在使用epoll进行联网编程。我遇到了分段错误错误,但由于它在多线程上运行,因此很难通过使用日志找到它确切地获取错误的位置。如何使用gdb进行多线程联网程序

我想使用gdb,所以我可以看到堆栈跟踪。如果我在gdb上运行这个,那么我从epoll_wait得到这个错误。如果我从不同的客户端连接到服务器,那么它根本不起作用。

我该如何解决这个问题,所以我可以使用gdb来找出它得到分段错误 在此先感谢..

epoll_wait error 
: Interrupted system call 
+0

你在C或C++吗? – Puppy

回答

3

您需要修复程序以正确处理EINTR。 EINTR(“中断系统调用”)不是致命错误;它只是意味着“请重试该系统调用”。因此,调用epoll_wait()的代码应该检测到它,然后只是默默地重试该调用。事情是这样的:

int rv; 
do { 
    rv = epoll_wait(epfd, events, maxevents, timeout); 
} while (rv == -1 && errno == EINTR); 

或者,如果你有一个固定的超时时间,你需要重新计算每一个电话:

int rv; 
rv = epoll_wait(epfd, events, maxevents, timeout); 
while (rv == -1 && errno == EINTR) { 
    ...TODO: recalculate timeout here... 
    rv = epoll_wait(epfd, events, maxevents, timeout); 
} 

如果你不知道这个没有,你可能在相同的错误您对其他系统呼叫的呼叫。特别是read()和write(),还有很多其他的调用 - 检查你使用的调用的手册页,看看他们是否将EINTR列为可能的错误。如果你使用任何使用信号的库,或者如果你自己使用信号,那么你可以得到EINTR,这通常是不切实际的。上次我查看时,Linux线程库使用了信号。

2

启用核心转储在您的环境中保存。运行命令ulimit -c unlimited并重新运行您的程序。当它崩溃时,在gdb中加载生成的核心转储并查看崩溃的后退。在多线程程序的情况下,一次只能通过一个命令从所有线程获得回溯:(gdb) thread apply all bt