Open shong99 opened 1 month ago
先升级到最新版本试试,这个版本太老了
因为我们在很多生产环境部署的drogon都是这个版本的,要升级的话需要一些流程。
目前我想问的是之前有没有在高负载环境下出现这种回调函数地址为非法的情况,这个问题在一个现场出现3次了
没被报过这个问题,可能有竞态条件,高负载触发的几率增大。 你们环境是使用drogon做client还是server?
是server端
这问题还能分析吗,回调函数这块我看的有点头大...
可以,你要debug编译,然后看coredump的调用堆栈看看崩在哪里了,再考虑修复,但是这个版本是两年前的,估计你修复了也没法在新的版本上打补丁了。只能报告一下错误原因,我再走查一下新版本是不是有这个问题。。。
本地压力测试可以复现吗
本地没复现出来,只在现场出现过
通过修改源码,我已经复现出问题了,主要修改的地方是两个,一个是socket的析构函数中屏蔽释放socket,另一个是epoll_ctl屏蔽对tcp的channel的取消注册,通过这种模拟可以复现出问题。
另外,现场环境替换了添加日志的drogon库trantor,通过日志也可以发现channel指针理论上应该被释放了,但是仍在调用read回调函数,所以应该是epoll删除这个指针失败,同时socket应该也没释放成功且还在接受消息
2024-08-28 18:03:03.672 - INFO - 139939166525184 - [drogon Info] connectDestroyed
2024-08-28 18:03:03.672 - INFO - 139939166525184 - [drogon Info] Channel: remove, chn ptr=0x5573D118F890 owner:0x5573D14C93D0 TcpConnectionImpl
2024-08-28 18:03:03.672 - INFO - 139939166525184 - [drogon Info] EventLoop: removeChannel
2024-08-28 18:03:03.672 - INFO - 139939166525184 - [drogon Info] EpollPoller::removeChannel
2024-08-28 18:03:03.672 - INFO - 139939166525184 - [drogon Info] ~TcpConnectionImpl: free ptr: 0x5573D14C93D0
2024-08-28 18:03:03.672 - INFO - 139939166525184 - [drogon Info] handleEventSafely: handle read:0x5573D118F8B0 chnP=0x5573D118F890 owner:0x5573D14C93D0
@an-tao @fantasy-peak
最新trantor也有这个问题吗
我刚看了一下, 你的意思是 EpollPoller::update 函数中 ::epollctl(epollfd, operation, fd, &event) 执行失败了对吗? https://github.com/an-tao/trantor/blob/65f245539215a8c25e04cd475c13d16044209a66/trantor/net/inner/poller/EpollPoller.cc#L183 https://github.com/an-tao/trantor/blob/65f245539215a8c25e04cd475c13d16044209a66/trantor/net/inner/poller/EpollPoller.cc#L203
是的,目前猜测是这样的
1.5.5
void TcpServer::handleCloseInLoop(const TcpConnectionPtr &connectionPtr)
{
size_t n = connSet_.erase(connectionPtr);
(void)n;
assert(n == 1);
auto connLoop = connectionPtr->getLoop();
if (connLoop == loop_)
{
static_cast<TcpConnectionImpl *>(connectionPtr.get())
->connectDestroyed();
}
else
{
connLoop->queueInLoop([connectionPtr]() {
static_cast<TcpConnectionImpl *>(connectionPtr.get())
->connectDestroyed();
});
}
}
最新的
void TcpServer::handleCloseInLoop(const TcpConnectionPtr &connectionPtr)
{
size_t n = connSet_.erase(connectionPtr);
(void)n;
assert(n == 1);
auto connLoop = connectionPtr->getLoop();
// NOTE: always queue this operation in connLoop, because this connection
// may be in loop_'s current active channels, waiting to be processed.
// If `connectDestroyed()` is called here, we will be using an wild pointer
// later.
connLoop->queueInLoop(
[connectionPtr]() { connectionPtr->connectDestroyed(); });
}
https://github.com/an-tao/trantor/pull/206 或许已经被修复了, 在最新版中
@shong99 升级最新版本了吗
在容器运行环境有出现过几次trantor库的异常,从堆栈内存分析似乎是访问的回调函数地址为非法的,但更具体的无法确认。运行环境的网络请求很频繁且数据量很大。
下面是通过栈指针查到的信息,handleEventSafely偏移地址92我通过反汇编猜测大概是readCallback_?
下面是寄存器信息和栈帧信息
版本信息: drogon 1.7.5 trantor 1.5.5