You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2026/03/30 22:00:12 UTC

(trafficserver) branch master updated: Fix memory leaks in core shutdown path (#13027)

This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 7ca87021ed Fix memory leaks in core shutdown path (#13027)
7ca87021ed is described below

commit 7ca87021edd52eb20520864d94becf53ef2fb1c3
Author: Bryan Call <bc...@apache.org>
AuthorDate: Mon Mar 30 15:00:05 2026 -0700

    Fix memory leaks in core shutdown path (#13027)
    
    * Fix NetAccept leak in stop_accept() — delete objects after
      stopping and clear naVec.
    
    * Fix acceptor objects leak — delete SSLNextProtocolAccept,
      ProtocolProbeSessionAccept, and plugin accepts in
      stop_HttpProxyServer().
    
    * Fix AIOCallback leak for API-originated AIO ops — add
      from_api flag, delete callback in io_complete and on
      error path.
---
 include/iocore/aio/AIO.h              |  1 +
 src/api/InkAPI.cc                     |  4 ++++
 src/iocore/aio/AIO.cc                 |  3 +++
 src/iocore/net/UnixNetProcessor.cc    |  4 +++-
 src/proxy/http/HttpProxyServerMain.cc | 12 ++++++++++++
 5 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/include/iocore/aio/AIO.h b/include/iocore/aio/AIO.h
index dfd14fa925..44cc1a0564 100644
--- a/include/iocore/aio/AIO.h
+++ b/include/iocore/aio/AIO.h
@@ -83,6 +83,7 @@ struct AIOCallback : public Continuation {
   int64_t    aio_result = 0;
   AIO_Reqs  *aio_req    = nullptr;
   ink_hrtime sleep_time = 0;
+  bool       from_api   = false;
   SLINK(AIOCallback, alink); /* for AIO_Reqs::aio_temp_list */
 #if TS_USE_LINUX_IO_URING
   iovec        iov     = {}; // this is to support older kernels that only support readv/writev
diff --git a/src/api/InkAPI.cc b/src/api/InkAPI.cc
index 8697e08b04..23009a5243 100644
--- a/src/api/InkAPI.cc
+++ b/src/api/InkAPI.cc
@@ -7067,11 +7067,13 @@ TSAIORead(int fd, off_t offset, char *buf, size_t buffSize, TSCont contp)
   pAIO->aiocb.aio_buf = buf;
   pAIO->action        = pCont;
   pAIO->thread        = pCont->mutex->thread_holding;
+  pAIO->from_api      = true;
 
   if (ink_aio_read(pAIO, 1) == 1) {
     return TS_SUCCESS;
   }
 
+  delete pAIO;
   return TS_ERROR;
 }
 
@@ -7106,11 +7108,13 @@ TSAIOWrite(int fd, off_t offset, char *buf, const size_t bufSize, TSCont contp)
   pAIO->aiocb.aio_nbytes = bufSize;
   pAIO->action           = pCont;
   pAIO->thread           = pCont->mutex->thread_holding;
+  pAIO->from_api         = true;
 
   if (ink_aio_write(pAIO, 1) == 1) {
     return TS_SUCCESS;
   }
 
+  delete pAIO;
   return TS_ERROR;
 }
 
diff --git a/src/iocore/aio/AIO.cc b/src/iocore/aio/AIO.cc
index 0f69f51d3e..2b14cfa7f3 100644
--- a/src/iocore/aio/AIO.cc
+++ b/src/iocore/aio/AIO.cc
@@ -99,6 +99,9 @@ AIOCallback::io_complete(int event, void *data)
   if (!action.cancelled && action.continuation) {
     action.continuation->handleEvent(AIO_EVENT_DONE, this);
   }
+  if (from_api) {
+    delete this;
+  }
   return EVENT_DONE;
 }
 
diff --git a/src/iocore/net/UnixNetProcessor.cc b/src/iocore/net/UnixNetProcessor.cc
index 5c8d5111e1..950ea5d287 100644
--- a/src/iocore/net/UnixNetProcessor.cc
+++ b/src/iocore/net/UnixNetProcessor.cc
@@ -167,9 +167,11 @@ void
 UnixNetProcessor::stop_accept()
 {
   SCOPED_MUTEX_LOCK(lock, naVecMutex, this_ethread());
-  for (auto &na : naVec) {
+  for (auto *na : naVec) {
     na->stop_accept();
+    delete na;
   }
+  naVec.clear();
 }
 
 Action *
diff --git a/src/proxy/http/HttpProxyServerMain.cc b/src/proxy/http/HttpProxyServerMain.cc
index 3f9dc8e984..ed4431adf0 100644
--- a/src/proxy/http/HttpProxyServerMain.cc
+++ b/src/proxy/http/HttpProxyServerMain.cc
@@ -376,4 +376,16 @@ stop_HttpProxyServer()
 {
   sslNetProcessor.stop_accept();
   netProcessor.stop_accept();
+
+  for (auto &acceptor : HttpProxyAcceptors) {
+    delete acceptor._accept;
+    acceptor._accept = nullptr;
+  }
+  HttpProxyAcceptors.clear();
+
+  delete plugin_http_accept;
+  plugin_http_accept = nullptr;
+
+  delete plugin_http_transparent_accept;
+  plugin_http_transparent_accept = nullptr;
 }