From dd3e7ff973cdf2d70d3a0a7400a8c2e23724b910 Mon Sep 17 00:00:00 2001 From: Jesse Zhang Date: Mon, 13 Jul 2020 12:15:42 -0700 Subject: [PATCH] Do not allocate MemoryPoolManager from a memory pool Our implementations of memory pools have a hidden dependency on _the_ global memory pool manager: typically GPOS_NEW and GPOS_DELETE will reach for the memory pool manager singleton. This makes GPOS_DELETE on a memory pool manager undefined behavior because we call member functions on an object after its destructor finishes. On the Postgres 12 merge branch, this manifests itself in a crash during initdb. More concerning is that it only crashed when we set max connections and shared buffers to a specific number. --- .../gporca/libgpos/include/gpos/memory/CMemoryPoolManager.h | 4 ++-- src/backend/gporca/libgpos/src/memory/CMemoryPoolManager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/gporca/libgpos/include/gpos/memory/CMemoryPoolManager.h b/src/backend/gporca/libgpos/include/gpos/memory/CMemoryPoolManager.h index 621c4f9b2b..da0d8c4590 100644 --- a/src/backend/gporca/libgpos/include/gpos/memory/CMemoryPoolManager.h +++ b/src/backend/gporca/libgpos/include/gpos/memory/CMemoryPoolManager.h @@ -112,12 +112,12 @@ namespace gpos void *alloc_internal = gpos::clib::Malloc(sizeof(PoolType)); // create internal memory pool - CMemoryPool *internal = new(alloc_internal) PoolType(); + CMemoryPool *internal = ::new(alloc_internal) PoolType(); // instantiate manager GPOS_TRY { - m_memory_pool_mgr = GPOS_NEW(internal) ManagerType(internal, EMemoryPoolTracker); + m_memory_pool_mgr = ::new ManagerType(internal, EMemoryPoolTracker); m_memory_pool_mgr->Setup(); } GPOS_CATCH_EX(ex) diff --git a/src/backend/gporca/libgpos/src/memory/CMemoryPoolManager.cpp b/src/backend/gporca/libgpos/src/memory/CMemoryPoolManager.cpp index 1866390fe3..273f17feb4 100644 --- a/src/backend/gporca/libgpos/src/memory/CMemoryPoolManager.cpp +++ b/src/backend/gporca/libgpos/src/memory/CMemoryPoolManager.cpp @@ -283,7 +283,7 @@ CMemoryPoolManager::Shutdown() // save off pointers for explicit deletion CMemoryPool *internal = m_internal_memory_pool; - GPOS_DELETE(CMemoryPoolManager::m_memory_pool_mgr); + ::delete CMemoryPoolManager::m_memory_pool_mgr; CMemoryPoolManager::m_memory_pool_mgr = NULL; #ifdef GPOS_DEBUG -- GitLab