Linux下Epoll服务器清理客户端端口信息时触发double free错误求助
排查epoll服务器中"double free or corruption (out)"错误
问题核心原因
你遇到的double free错误是重复释放同一个内存块导致的:
- 在
receiveDataFromSctp函数中,你连续调用了两次cleanHashEntry,传入的是同一个ConnectedCU_t指针:cleanHashEntry((ConnectedCU_t *) events->data.ptr, GlobalMap1); cleanHashEntry((ConnectedCU_t *) events->data.ptr, GlobalMap2); - 而
cleanHashEntry函数的末尾会执行free(val),这就导致同一个ConnectedCU_t结构体被释放了两次,触发内存损坏错误。
另外,你的逻辑存在误区:GlobalMap1和GlobalMap2存储的是ConnectedCU_t的指针,不是独立的结构体副本。清理哈希表只需要移除对应的条目,不需要重复释放结构体本身——结构体的内存只需要释放一次。
修复方案
步骤1:修改cleanHashEntry,移除重复释放逻辑
把cleanHashEntry中的free(val)操作删掉,让它只负责清理哈希表条目:
void cleanHashEntry(ConnectedCU_t *val, Sctp_Map_t *m) { if(val != nullptr) { char *dummy; auto port = (uint16_t) strtol(val->portNumber, &dummy, 10); char searchBuff[2048]{}; snprintf(searchBuff, sizeof searchBuff, "host:%s:%d", val->hostName, port); if(m->find(searchBuff)) { m->erase(searchBuff); } if(m->find(val->enodbName)) { m->erase(val->enodbName); } // 移除这里的free(val)操作 } }
步骤2:在receiveDataFromSctp中统一释放内存
调用两次cleanHashEntry清理完两个哈希表后,再一次性释放ConnectedCU_t结构体:
if (done) { mdclog_write(MDCLOG_INFO, "Closed connection - descriptor = %d", message.peerInfo->fileDescriptor); pthread_mutex_lock(&thread_lock); if (fcntl(message.peerInfo->fileDescriptor, F_GETFD) != -1) { mdclog_write(MDCLOG_DEBUG, "Closing connection - descriptor = %d", message.peerInfo->fileDescriptor); close(message.peerInfo->fileDescriptor); // 先清理两个哈希表的条目 cleanHashEntry((ConnectedCU_t *) events->data.ptr, GlobalMap1); cleanHashEntry((ConnectedCU_t *) events->data.ptr, GlobalMap2); // 仅释放一次结构体内存 ConnectedCU_t *peer = (ConnectedCU_t *) events->data.ptr; if(peer) { free(peer); peer = nullptr; } } pthread_mutex_unlock(&thread_lock); }
额外注意点
因为服务器使用多线程监听epoll,要确保同一个连接的关闭事件不会被多个线程并发处理。当前代码已经通过pthread_mutex_lock(&thread_lock)加锁,需确认thread_lock是全局唯一的,且所有操作哈希表、释放资源的路径都持有该锁,避免并发问题。
内容的提问来源于stack exchange,提问作者myquest9 sh
相关产品推荐
相关产品推荐

