如何将gdb用于多线程网络程序

时间:2011-07-25 08:50:05

标签: c++ c linux networking gdb

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

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

如何解决这个问题,以便我可以使用gdb找出它出现分段错误的错误 提前谢谢..

epoll_wait error
: Interrupted system call

2 个答案:

答案 0 :(得分: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发生通常是不切实际的 - 如果您使用任何使用信号的库,或者您自己使用信号,那么您可以获得EINTR。上次我看,Linux线程库使用了信号。

答案 1 :(得分:2)

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