]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
test/erasure-code: fix memory leak when erasure_code_init() fails 64221/head
authorKefu Chai <tchaikov@gmail.com>
Fri, 27 Jun 2025 03:05:17 +0000 (11:05 +0800)
committerKefu Chai <tchaikov@gmail.com>
Fri, 27 Jun 2025 03:28:16 +0000 (11:28 +0800)
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<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
> 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 <tchaikov@gmail.com>
src/test/erasure-code/ErasureCodePluginExample.cc

index 697b77d94f54684c32cd52e1b55f7b9f7d832d79..22de30cfe9a27567563171288953dc407d6557c7 100644 (file)
@@ -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<ErasureCodeExample>();
+    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<ErasureCodePluginExample>();
+  int r = instance.add(plugin_name, plugin.get());
+  if (r == 0) {
+    std::ignore = plugin.release();
+  }
+  return r;
 }