![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | yosagi |
Hi.
I’m trying to read (and modify) InputMap from C++ via GDNative.
I could write a code to access InputMap, but it makes the engine crash on exit.
The root cause seems something related to reference counting. Any advise please?
Platform: Windows 64bit
Version: 3.1.1.stable.official, 3.2.dev.custom_build.d2f38dbb2
A following code fragment is a core part of my code.
void godot::MyNode::_init()
{
godot::Array al = godot::InputMap::get_singleton()->get_actions();
for (int idx = 0; idx < al.size(); ++idx) {
const godot::Array events= godot::InputMap::get_singleton()->get_action_list(al[idx]);
for (int ei = 0; ei < events.size(); ei++) {
const Ref<InputEvent> ev = events[ei];
//const InputEvent *ev = events[ei];
Referencing ‘events[ei]’ with Ref or raw pointer causes the crash with a following message.
ERROR: ScriptServer::get_language: Index p_idx=0 out of size (_language_count=0)
At: core\script_language.cpp:84
Simplified stack trace:
godot.windows.tools.64.exe!Reference::unreference() Line 97 C++
godot.windows.tools.64.exe!Ref<Reference>::unref() Line 280 C++
godot.windows.tools.64.exe!RefPtr::unref() Line 83 C++
godot.windows.tools.64.exe!Variant::clear() Line 1111 C++
godot.windows.tools.64.exe!Variant::~Variant() Line 422 C++
godot.windows.tools.64.exe!CowData<Variant>::~CowData<Variant>() Line 369 C++
godot.windows.tools.64.exe!Vector<Variant>::~Vector<Variant>() Line 126 C++
godot.windows.tools.64.exe!Array::~Array() Line 421 C++
godot.windows.tools.64.exe!Variant::~Variant() Line 422 C++
godot.windows.tools.64.exe!List<Pair<Variant const *,Variant>,DefaultAllocator>::~List<Pair<Variant const *,Variant>,DefaultAllocator>() Line 711 C++
godot.windows.tools.64.exe!Dictionary::~Dictionary() Line 289 C++
godot.windows.tools.64.exe!Variant::~Variant() Line 422 C++
godot.windows.tools.64.exe!memdelete_allocator<Map<StringName,ProjectSettings::VariantContainer,Comparator<StringName>,DefaultAllocator>::Element,DefaultAllocator>(Map<StringName,ProjectSettings::VariantContainer,Comparator<StringName>,DefaultAllocator>::Element * p_class) Line 133 C++
godot.windows.tools.64.exe!Map<StringName,ProjectSettings::VariantContainer,Comparator<StringName>,DefaultAllocator>::~Map<StringName,ProjectSettings::VariantContainer,Comparator<StringName>,DefaultAllocator>() Line 684 C++
godot.windows.tools.64.exe!ProjectSettings::~ProjectSettings() Line 1212 C++
godot.windows.tools.64.exe!Main::cleanup() Line 2094 C++
The code around Reference::unreference():97:
if (instance_binding_count > 0) {
for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
if (_script_instance_bindings[i]) {
bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this);
die = die && script_ret;
}
}
}
‘instance_binding_count’ was 1. Since ScriptServer::finish_languages() was called before Main::cleanup():2094 (at Main::cleanup():2055), I think ‘instance_binding_count’ should not be non-zero at this point.
But I could not find how this condition can be achieved.
I’ve copy-pasted the wrong stack trace on my post. The stack trace I showed was not a result from the code alone. It was produced with the code and a cleanup code below:
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o)
{
godot::Array al=godot::InputMap::get_singleton()->get_actions();
for (int idx = 0; idx < al.size(); ++idx) {
godot::InputMap::get_singleton()->erase_action(al[idx]);
}
godot::Godot::gdnative_terminate(o);
}
Without this cleanup code, the engine crashes at earlier stage with the similar reason.
godot.windows.tools.64.exe!Reference::unreference() Line 97 C++
godot.windows.tools.64.exe!Ref<InputEvent>::unref() Line 280 C++
godot.windows.tools.64.exe!Ref<InputEvent>::~Ref<InputEvent>() Line 298 C++
[External Code]
godot.windows.tools.64.exe!memdelete_allocator<List<Ref<InputEvent>,DefaultAllocator>::Element,DefaultAllocator>(List<Ref<InputEvent>,DefaultAllocator>::Element * p_class) Line 133 C++
godot.windows.tools.64.exe!List<Ref<InputEvent>,DefaultAllocator>::_Data::erase(const List<Ref<InputEvent>,DefaultAllocator>::Element * p_I) Line 174 C++
godot.windows.tools.64.exe!List<Ref<InputEvent>,DefaultAllocator>::erase(const List<Ref<InputEvent>,DefaultAllocator>::Element * p_I) Line 368 C++
godot.windows.tools.64.exe!List<Ref<InputEvent>,DefaultAllocator>::clear() Line 405 C++
godot.windows.tools.64.exe!List<Ref<InputEvent>,DefaultAllocator>::~List<Ref<InputEvent>,DefaultAllocator>() Line 711 C++
[External Code]
godot.windows.tools.64.exe!memdelete_allocator<Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::Element,DefaultAllocator>(Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::Element * p_class) Line 133 C++
godot.windows.tools.64.exe!Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::_cleanup_tree(Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::Element * p_element) Line 509 C++
godot.windows.tools.64.exe!Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::_cleanup_tree(Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::Element * p_element) Line 507 C++
godot.windows.tools.64.exe!Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::_cleanup_tree(Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::Element * p_element) Line 507 C++
godot.windows.tools.64.exe!Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::clear() Line 664 C++
godot.windows.tools.64.exe!Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>::~Map<StringName,InputMap::Action,Comparator<StringName>,DefaultAllocator>() Line 684 C++
[External Code]
godot.windows.tools.64.exe!memdelete<InputMap>(InputMap * p_class) Line 122 C++
godot.windows.tools.64.exe!Main::cleanup() Line 2090 C++
godot.windows.tools.64.exe!widechar_main(int argc, wchar_t * * argv) Line 153 C++
godot.windows.tools.64.exe!_main() Line 173 C++
godot.windows.tools.64.exe!main(int _argc, char * * _argv) Line 185 C++
yosagi | 2019-10-23 03:55