本文主要是介绍问题排查|记录一次基于mymuduo库开发的服务器错误排查(段错误--Segmentation fault (core dumped)),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题记录:
在刚完成mymuduo库之后,写了一个简单的测试服务器,
但是在服务器运行后直接报错:cherry@hcss-ecs-4995:~/mymuduo/example$ ./testserver Segmentation fault (core dumped)
出现多错误这通常意味着程序试图访问其内存空间中未分配(或不允许)的部分。
所以我决定先使用gdb进行一下简单的调试:
gdb ./testserver
把程序跑起来之后马上定位到了报错位置:
Program received signal SIGSEGV, Segmentation fault.
EventLoop::updateChannel (this=0x7fffffffdd60, channel=0x555555572eb0) at /home/cherry/mymuduo/EventLoop.cc:126
126 poller_->updateChannel(channel);
我再查看代码:
125 void EventLoop::updateChannel(Channel *channel) {
126 poller_->updateChannel(channel);
127 }
既然是段错误,说明我们访问了不被允许访问的内存,或者操作了不被允许操作的内存。
接下来我们有以下三个主要的思路:
(gdb) print poller_ #poller是否是空
(gdb) print channel #channel是否为空
(gdb) print *channel #如果channel不是空,那么它是否指向了有效对象,该对象状态是否正常?
(gdb) backtrace #如果都正常,查看调用栈,是哪里调用了 EventLoop::updateChannel 方法
但是比较悲剧的是,我直接 print poller_
就发现我们重要的poller对象竟然是空!
所以我马上去看了一下构造函数代码是否正常
EventLoop::EventLoop(): looping_(false), quit_(false), callingPendingFunctors_(false), threadId_(CurrentThread::tid()), poller_(Poller::newDefaultPoller(this)), wakeupFd_(createEventfd()), wakeupChannel_(new Channel(this, wakeupFd_))
在构造函数中, poller_
的初始化是通过newDefaultPoller
来完成的,那么去看看它是否正常工作:
Poller* Poller::newDefaultPoller(EventLoop *loop) {if (::getenv("MUDUO_USE_POLL")) {return nullptr; // 生成poll的实例} else {return nullptr; // 生成epoll的实例}
}
好巧不巧,我们竟然在生成epoll实例的地方返回了一个空!之前在写这个代码的时候还没有完成EpollPoller.h
文件的书写,为了防止部分编译报错所以先写成空了。
更改代码如下:
#include "EpollPoller.h"
return new EPollPoller(loop);
这篇关于问题排查|记录一次基于mymuduo库开发的服务器错误排查(段错误--Segmentation fault (core dumped))的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!