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>
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;
}
};
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;
}