Repository: godot
Issue: Possible memory leak in gdextension.cpp when method names are duplicated
Labels: bug,needs testing,topic:gdextension

### Tested versions

nightly

### System information

linux

### Issue description

While working on something unrelated, I got a memcheck failure in CI: https://github.com/godot-rust/gdext/actions/runs/12881698201/job/35912681146#step:3:1706

<details>

```
=================================================================
==3088==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 232 byte(s) in 1 object(s) allocated from:
    #0 0x55ba3602b62e in malloc (/home/runner/work/_temp/godot_bin/godot.linuxbsd.editor.dev.x86_64.llvm.san+0x21c9c62e) (BuildId: 874db2a84ccfa9b3)
    #1 0x55ba55e654e6 in Memory::alloc_static(unsigned long, bool) /home/runner/work/godot4-nightly/godot4-nightly/core/os/memory.cpp:106:14
    #2 0x55ba55e65362 in operator new(unsigned long, char const*) /home/runner/work/godot4-nightly/godot4-nightly/core/os/memory.cpp:39:9
    #3 0x55ba58953974 in GDExtension::_register_extension_class_method(void*, void const*, GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:509:12
    #4 0x7f5c738209e0 in godot_core::registry::method::ClassMethodInfo::register_nonvirtual_class_method::h6f44d6b7c80457d4 /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:157:13
    #5 0x7f5c7381fff8 in godot_core::registry::method::ClassMethodInfo::register_extension_class_method::hfb75fa1a2544ea5f /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:147:13
    #6 0x7f5c730ae1e2 in itest::register_tests::func_test::_::__init::__inner_init::_$u7b$$u7b$closure$u7d$$u7d$::h9ae97532f88693d3 /home/runner/work/gdext/gdext/itest/rust/src/register_tests/func_test.rs:79:1
    #7 0x7f5c72dbfffd in core::ops::function::FnOnce::call_once::h0a8edd5c08646abf /rustc/f3d1d47fd84dfcf7f513be1dbad356e74c8f3b2b/library/core/src/ops/function.rs:250:5
    #8 0x7f5c72c230a2 in godot_core::registry::callbacks::register_user_methods_constants::ha0604185de96699d /home/runner/work/gdext/gdext/godot-core/src/registry/callbacks.rs:392:5
    #9 0x7f5c7381756d in godot_core::registry::class::auto_register_classes::h71cfbbdffdad7470 /home/runner/work/gdext/gdext/godot-core/src/registry/class.rs:228:9
    #10 0x7f5c7386886c in godot_core::init::gdext_on_level_init::h1d4172dd01e950e9 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:161:5
    #11 0x7f5c72fd3a5a in godot_core::init::ffi_initialize_layer::_$u7b$$u7b$closure$u7d$$u7d$::hdf873678b0f13b97 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:107:9
    #12 0x7f5c71290641 in godot_core::private::handle_panic_with_print::h4b774d0a828afef5 /home/runner/work/gdext/gdext/godot-core/src/private.rs:377:17
    #13 0x7f5c70cf8878 in godot_core::private::handle_panic::h129b9f0e49e1359a /home/runner/work/gdext/gdext/godot-core/src/private.rs:275:5
    #14 0x55ba5895bbdd in GDExtension::initialize_library(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:745:2
    #15 0x55ba589f5fb1 in GDExtensionManager::initialize_extensions(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension_manager.cpp:228:12
    #16 0x55ba364c1f2b in Main::setup2(bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:3381:40
    #17 0x55ba364aed45 in Main::setup(char const*, int, char**, bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:2676:14
    #18 0x55ba36068f93 in main /home/runner/work/godot4-nightly/godot4-nightly/platform/linuxbsd/godot_linuxbsd.cpp:74:14
    #19 0x7f5c7be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)

Direct leak of 232 byte(s) in 1 object(s) allocated from:
    #0 0x55ba3602b62e in malloc (/home/runner/work/_temp/godot_bin/godot.linuxbsd.editor.dev.x86_64.llvm.san+0x21c9c62e) (BuildId: 874db2a84ccfa9b3)
    #1 0x55ba55e654e6 in Memory::alloc_static(unsigned long, bool) /home/runner/work/godot4-nightly/godot4-nightly/core/os/memory.cpp:106:14
    #2 0x55ba55e65362 in operator new(unsigned long, char const*) /home/runner/work/godot4-nightly/godot4-nightly/core/os/memory.cpp:39:9
    #3 0x55ba58953974 in GDExtension::_register_extension_class_method(void*, void const*, GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:509:12
    #4 0x7f5c738209e0 in godot_core::registry::method::ClassMethodInfo::register_nonvirtual_class_method::h6f44d6b7c80457d4 /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:157:13
    #5 0x7f5c7381fff8 in godot_core::registry::method::ClassMethodInfo::register_extension_class_method::hfb75fa1a2544ea5f /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:147:13
    #6 0x7f5c730ae00f in itest::register_tests::func_test::_::__init::__inner_init::_$u7b$$u7b$closure$u7d$$u7d$::h9ae97532f88693d3 /home/runner/work/gdext/gdext/itest/rust/src/register_tests/func_test.rs:79:1
    #7 0x7f5c72dbfffd in core::ops::function::FnOnce::call_once::h0a8edd5c08646abf /rustc/f3d1d47fd84dfcf7f513be1dbad356e74c8f3b2b/library/core/src/ops/function.rs:250:5
    #8 0x7f5c72c230a2 in godot_core::registry::callbacks::register_user_methods_constants::ha0604185de96699d /home/runner/work/gdext/gdext/godot-core/src/registry/callbacks.rs:392:5
    #9 0x7f5c7381756d in godot_core::registry::class::auto_register_classes::h71cfbbdffdad7470 /home/runner/work/gdext/gdext/godot-core/src/registry/class.rs:228:9
    #10 0x7f5c7386886c in godot_core::init::gdext_on_level_init::h1d4172dd01e950e9 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:161:5
    #11 0x7f5c72fd3a5a in godot_core::init::ffi_initialize_layer::_$u7b$$u7b$closure$u7d$$u7d$::hdf873678b0f13b97 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:107:9
    #12 0x7f5c71290641 in godot_core::private::handle_panic_with_print::h4b774d0a828afef5 /home/runner/work/gdext/gdext/godot-core/src/private.rs:377:17
    #13 0x7f5c70cf8878 in godot_core::private::handle_panic::h129b9f0e49e1359a /home/runner/work/gdext/gdext/godot-core/src/private.rs:275:5
    #14 0x55ba5895bbdd in GDExtension::initialize_library(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:745:2
    #15 0x55ba589f5fb1 in GDExtensionManager::initialize_extensions(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension_manager.cpp:228:12
    #16 0x55ba364c1f2b in Main::setup2(bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:3381:40
    #17 0x55ba364aed45 in Main::setup(char const*, int, char**, bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:2676:14
    #18 0x55ba36068f93 in main /home/runner/work/godot4-nightly/godot4-nightly/platform/linuxbsd/godot_linuxbsd.cpp:74:14
    #19 0x7f5c7be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)

Indirect leak of 20 byte(s) in 1 object(s) allocated from:
    #0 0x55ba3602b62e in malloc (/home/runner/work/_temp/godot_bin/godot.linuxbsd.editor.dev.x86_64.llvm.san+0x21c9c62e) (BuildId: 874db2a84ccfa9b3)
    #1 0x55ba55e654e6 in Memory::alloc_static(unsigned long, bool) /home/runner/work/godot4-nightly/godot4-nightly/core/os/memory.cpp:106:14
    #2 0x55ba3957bf2d in Variant::Type* memnew_arr_template<Variant::Type>(unsigned long) /home/runner/work/godot4-nightly/godot4-nightly/./core/os/memory.h:180:28
    #3 0x55ba58b24fc5 in MethodBind::_generate_argument_types(int) /home/runner/work/godot4-nightly/godot4-nightly/core/object/method_bind.cpp:104:24
    #4 0x55ba5898964e in GDExtensionMethodBind::update(GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:223:3
    #5 0x55ba5896bf65 in GDExtensionMethodBind::GDExtensionMethodBind(GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:237:3
    #6 0x55ba589539b7 in GDExtension::_register_extension_class_method(void*, void const*, GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:509:12
    #7 0x7f5c738209e0 in godot_core::registry::method::ClassMethodInfo::register_nonvirtual_class_method::h6f44d6b7c80457d4 /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:157:13
    #8 0x7f5c7381fff8 in godot_core::registry::method::ClassMethodInfo::register_extension_class_method::hfb75fa1a2544ea5f /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:147:13
    #9 0x7f5c730ae1e2 in itest::register_tests::func_test::_::__init::__inner_init::_$u7b$$u7b$closure$u7d$$u7d$::h9ae97532f88693d3 /home/runner/work/gdext/gdext/itest/rust/src/register_tests/func_test.rs:79:1
    #10 0x7f5c72dbfffd in core::ops::function::FnOnce::call_once::h0a8edd5c08646abf /rustc/f3d1d47fd84dfcf7f513be1dbad356e74c8f3b2b/library/core/src/ops/function.rs:250:5
    #11 0x7f5c72c230a2 in godot_core::registry::callbacks::register_user_methods_constants::ha0604185de96699d /home/runner/work/gdext/gdext/godot-core/src/registry/callbacks.rs:392:5
    #12 0x7f5c7381756d in godot_core::registry::class::auto_register_classes::h71cfbbdffdad7470 /home/runner/work/gdext/gdext/godot-core/src/registry/class.rs:228:9
    #13 0x7f5c7386886c in godot_core::init::gdext_on_level_init::h1d4172dd01e950e9 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:161:5
    #14 0x7f5c72fd3a5a in godot_core::init::ffi_initialize_layer::_$u7b$$u7b$closure$u7d$$u7d$::hdf873678b0f13b97 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:107:9
    #15 0x7f5c71290641 in godot_core::private::handle_panic_with_print::h4b774d0a828afef5 /home/runner/work/gdext/gdext/godot-core/src/private.rs:377:17
    #16 0x7f5c70cf8878 in godot_core::private::handle_panic::h129b9f0e49e1359a /home/runner/work/gdext/gdext/godot-core/src/private.rs:275:5
    #17 0x55ba5895bbdd in GDExtension::initialize_library(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:745:2
    #18 0x55ba589f5fb1 in GDExtensionManager::initialize_extensions(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension_manager.cpp:228:12
    #19 0x55ba364c1f2b in Main::setup2(bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:3381:40
    #20 0x55ba364aed45 in Main::setup(char const*, int, char**, bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:2676:14
    #21 0x55ba36068f93 in main /home/runner/work/godot4-nightly/godot4-nightly/platform/linuxbsd/godot_linuxbsd.cpp:74:14
    #22 0x7f5c7be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)

Indirect leak of 20 byte(s) in 1 object(s) allocated from:
    #0 0x55ba3602b62e in malloc (/home/runner/work/_temp/godot_bin/godot.linuxbsd.editor.dev.x86_64.llvm.san+0x21c9c62e) (BuildId: 874db2a84ccfa9b3)
    #1 0x55ba55e654e6 in Memory::alloc_static(unsigned long, bool) /home/runner/work/godot4-nightly/godot4-nightly/core/os/memory.cpp:106:14
    #2 0x55ba3957bf2d in Variant::Type* memnew_arr_template<Variant::Type>(unsigned long) /home/runner/work/godot4-nightly/godot4-nightly/./core/os/memory.h:180:28
    #3 0x55ba58b24fc5 in MethodBind::_generate_argument_types(int) /home/runner/work/godot4-nightly/godot4-nightly/core/object/method_bind.cpp:104:24
    #4 0x55ba5898964e in GDExtensionMethodBind::update(GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:223:3
    #5 0x55ba5896bf65 in GDExtensionMethodBind::GDExtensionMethodBind(GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:237:3
    #6 0x55ba589539b7 in GDExtension::_register_extension_class_method(void*, void const*, GDExtensionClassMethodInfo const*) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:509:12
    #7 0x7f5c738209e0 in godot_core::registry::method::ClassMethodInfo::register_nonvirtual_class_method::h6f44d6b7c80457d4 /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:157:13
    #8 0x7f5c7381fff8 in godot_core::registry::method::ClassMethodInfo::register_extension_class_method::hfb75fa1a2544ea5f /home/runner/work/gdext/gdext/godot-core/src/registry/method.rs:147:13
    #9 0x7f5c730ae00f in itest::register_tests::func_test::_::__init::__inner_init::_$u7b$$u7b$closure$u7d$$u7d$::h9ae97532f88693d3 /home/runner/work/gdext/gdext/itest/rust/src/register_tests/func_test.rs:79:1
    #10 0x7f5c72dbfffd in core::ops::function::FnOnce::call_once::h0a8edd5c08646abf /rustc/f3d1d47fd84dfcf7f513be1dbad356e74c8f3b2b/library/core/src/ops/function.rs:250:5
    #11 0x7f5c72c230a2 in godot_core::registry::callbacks::register_user_methods_constants::ha0604185de96699d /home/runner/work/gdext/gdext/godot-core/src/registry/callbacks.rs:392:5
    #12 0x7f5c738[1756](https://github.com/godot-rust/gdext/actions/runs/12881698201/job/35912681146#step:3:1772)d in godot_core::registry::class::auto_register_classes::h71cfbbdffdad7470 /home/runner/work/gdext/gdext/godot-core/src/registry/class.rs:228:9
    #13 0x7f5c7386886c in godot_core::init::gdext_on_level_init::h1d4172dd01e950e9 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:161:5
    #14 0x7f5c72fd3a5a in godot_core::init::ffi_initialize_layer::_$u7b$$u7b$closure$u7d$$u7d$::hdf873678b0f13b97 /home/runner/work/gdext/gdext/godot-core/src/init/mod.rs:107:9
    #15 0x7f5c71290641 in godot_core::private::handle_panic_with_print::h4b774d0a828afef5 /home/runner/work/gdext/gdext/godot-core/src/private.rs:377:17
    #16 0x7f5c70cf8878 in godot_core::private::handle_panic::h129b9f0e49e1359a /home/runner/work/gdext/gdext/godot-core/src/private.rs:275:5
    #17 0x55ba5895bbdd in GDExtension::initialize_library(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension.cpp:745:2
    #18 0x55ba589f5fb1 in GDExtensionManager::initialize_extensions(GDExtension::InitializationLevel) /home/runner/work/godot4-nightly/godot4-nightly/core/extension/gdextension_manager.cpp:228:12
    #19 0x55ba364c1f2b in Main::setup2(bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:3381:40
    #20 0x55ba364aed45 in Main::setup(char const*, int, char**, bool) /home/runner/work/godot4-nightly/godot4-nightly/main/main.cpp:2676:14
    #21 0x55ba36068f93 in main /home/runner/work/godot4-nightly/godot4-nightly/platform/linuxbsd/godot_linuxbsd.cpp:74:14
    #22 0x7f5c7be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)

SUMMARY: AddressSanitizer: 504 byte(s) leaked in 4 allocation(s).
```

</details>

Looking into that error, ``method`` is allocated in L509 and passed into ``ClassDB::bind_method_custom``.

https://github.com/godotengine/godot/blob/1b7b009674e05b566be11a5377b935f5d3d6c0ee/core/extension/gdextension.cpp#L508-L520

If, for some reason, a method with the same name was already registered, it returns an error:

https://github.com/godotengine/godot/blob/1b7b009674e05b566be11a5377b935f5d3d6c0ee/core/object/class_db.cpp#L1879-L1882


The fix might be as simple as freeing ``p_method`` before returning.


### Steps to reproduce

none

### Minimal reproduction project (MRP)

none