首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ Linux Socket 服務端雙重釋放導致 glibc detected double free:gdb 定位釋放點修復

     編輯:程式設計綜合問答

錯誤現象

客戶端 `Ctrl+C` 斷開後,服務端崩潰:

*** glibc detected *** ./server: double free or corruption (fasttop): 0x09a2f028 ***
Backtrace:
./server[0x80497b8]
./server[0x80495ac]
...

根因

同一指針被 `free`/`delete` 了兩次。常見場景:

  • 線程池中多線程同時處理同一連接,析構函數重複釋放資源。
  • 容器(如 `std::vector`)存儲裸指針,`erase` 時未釋放,後來統一清理時再次釋放。
  • 異常拋出導致析構函數重複執行(罕見但可能)。

gdb 定位具體代碼行

gdb ./server
(gdb) run
# 觸發崩潰後
(gdb) bt
# 查看堆疊幀 0x80497b8、0x80495ac 對應的源碼行
(gdb) info line *0x80497b8
(gdb) info line *0x80495ac

典型修復模式

1. 使用智能指針(C++11 推薦)

#include <memory>
std::unique_ptr conn = std::make_unique(fd);
// 自動管理生命週期,杜絕 double free

2. 手動管理時遵循「誰分配誰釋放、置空防重複」

if (ptr) { free(ptr); ptr = NULL; }

3. 容器存儲對象而非裸指針

std::vector conns; // 值語義,自動析構
// 或
std::vector> conns;

排查清單

  1. 搜索代碼中所有 `free`/`delete`,確認每個指針**只有一處釋放**。
  2. 檢查多線程同步:連接關閉時是否有競態條件導致雙重進入清理邏輯。
  3. 啟用編譯器檢查:`-fsanitize=address` (GCC/Clang) 運行時自動檢測 double free。

用 gdb 定位崩潰地址對應的源碼行,改用智能指針或嚴格所有權管理,徹底解決 double free。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved