我如何使用gdb多线程网络程序

How do I use gdb for multi threaded networking program

本文关键字:网络 程序 多线程 gdb 何使用      更新时间:2023-10-16

我正在使用epoll进行网络编程。我得到一个分段错误,但由于它在多线程上运行,很难找到它确切地通过使用日志得到错误。

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

我如何解决这个问题,这样我就可以使用gdb找出它在哪里得到分段错误提前感谢……

epoll_wait error
: Interrupted system call

您需要修复您的程序以正确处理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线程库使用了信号。

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