From 22aec47006657ce027b3d2793c74734ed76bd934 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Fri, 27 Jun 2025 11:05:17 +0800 Subject: [PATCH] test/erasure-code: fix memory leak when erasure_code_init() fails Fix a memory leak in ErasureCodePluginExample when plugin registration fails. The allocated ErasureCodePluginExample instance was not being freed if ErasureCodePluginRegistry::add() failed, which occurs in tests that intentionally register duplicate plugins. ASan detected the leak: ``` Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7f4501321a2d in operator new(unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:86 #1 0x7f4501a5914d in __erasure_code_init /home/kefu/dev/ceph/src/test/erasure-code/ErasureCodePluginExample.cc:44 #2 0x5589985be68d in ceph::ErasureCodePluginRegistry::load(std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator > const&, ceph::ErasureCodePlugin**, std::ostream*) /home/kefu/dev/ceph/src/erasure-code/ErasureCodePlugin.cc:149 #3 0x5589984984ee in ErasureCodePluginRegistryTest_all_Test::TestBody() /home/kefu/dev/ceph/src/test/erasure-code/TestErasureCodePlugin.cc:116 ``` Use unique_ptr to manage the plugin instance lifecycle, following the pattern used by other erasure code plugins. The instance is now automatically destroyed if registry addition fails. Signed-off-by: Kefu Chai --- .../erasure-code/ErasureCodePluginExample.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/test/erasure-code/ErasureCodePluginExample.cc b/src/test/erasure-code/ErasureCodePluginExample.cc index 697b77d94f546..22de30cfe9a27 100644 --- a/src/test/erasure-code/ErasureCodePluginExample.cc +++ b/src/test/erasure-code/ErasureCodePluginExample.cc @@ -30,8 +30,11 @@ public: ErasureCodeInterfaceRef *erasure_code, ostream *ss) override { - *erasure_code = ErasureCodeInterfaceRef(new ErasureCodeExample()); - (*erasure_code)->init(profile, ss); + auto ec = std::make_unique(); + if (int r = ec->init(profile, ss); r) { + return r; + } + erasure_code->reset(ec.release()); return 0; } }; @@ -40,6 +43,11 @@ const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } int __erasure_code_init(char *plugin_name, char *directory) { - ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); - return instance.add(plugin_name, new ErasureCodePluginExample()); + auto& instance = ErasureCodePluginRegistry::instance(); + auto plugin = std::make_unique(); + int r = instance.add(plugin_name, plugin.get()); + if (r == 0) { + std::ignore = plugin.release(); + } + return r; } -- 2.39.5