繁体   English   中英

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

[英]How do I use gdb for multi threaded networking program

我正在使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM