简体   繁体   English

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

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

I am working on a networking programming using epoll. 我正在使用epoll进行网络编程。 I am getting a segmentation fault error but since it's running on multi thread, it is hard to find where it exactly gets the error by using logs. 我遇到了分段错误错误,但是由于它是在多线程上运行的,因此很难通过使用日志来找到它确切地从哪里得到了错误。

I was trying to using gdb so I can see the stack trace. 我试图使用gdb,以便可以看到堆栈跟踪。 If I run this on gdb then I am getting this error from the epoll_wait. 如果我在gdb上运行此命令,那么我将从epoll_wait收到此错误。 If I connected to the server from different clients then it doesn't work at all. 如果我从其他客户端连接到服务器,则根本无法正常工作。

How do I fix this so I can use gdb to find out where it gets the segmentation fault error Thanks in advance.. 我该如何解决这个问题,以便可以使用gdb找出它在哪里出现分段错误错误,谢谢。

epoll_wait error
: Interrupted system call

You need to fix your program to handle EINTR correctly. 您需要修复程序才能正确处理EINTR。 EINTR ("Interrupted system call") is NOT a fatal error; EINTR(“中断的系统调用”)不是致命错误; it just means "please retry that system call again". 它只是意味着“请再次重试该系统调用”。 So your code that calls epoll_wait() should detect it and just silently retry the call. 因此,调用epoll_wait()的代码应该检测到它,然后以静默方式重试该调用。 Something like this: 像这样:

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

Or, if you have a fixed timeout you need to recalculate it every call: 或者,如果您有固定的超时时间,则需要在每次调用时重新计算该超时时间:

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);
}

If you didn't know about this, you probably have the same bug in your calls to other system calls. 如果您对此一无所知,则在调用其他系统调用时可能会遇到相同的错误。 Especially read() and write(), but also a lot of other calls - check the man pages for the calls you use, and see if they list EINTR as a possible error. 特别是read()和write(),还有许多其他调用-检查手册页以查找您使用的调用,并查看它们是否将EINTR列为可能的错误。

It's usually not practical to prevent EINTR from happening - if you use any library that uses signals, or if you use signals yourself, then you can get EINTR. 防止EINTR发生通常不切实际-如果您使用任何使用信号的库,或者您自己使用信号,则可以获得EINTR。 Last time I looked, the Linux threading libraries used signals. 上次查看时,Linux线程库使用了信号。

Enable core dump saving in your environment. 在您的环境中启用核心转储保存。 Run command ulimit -c unlimited and rerun your program. 运行命令ulimit -c unlimited并重新运行程序。 When it crashes, load generated core dump in gdb and look backtraces of crash. 崩溃时,将生成的核心转储加载到gdb中,并查看崩溃的回溯。 In case of multi threaded program it is convenient to obtain backtraces from all threads by one command at once: (gdb) thread apply all bt . 在多线程程序的情况下,方便的是一次通过一个命令从所有线程获取回溯: (gdb) thread apply all bt

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

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