Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NativeScript 1.1] Crash attempting to get physics inside of a local resource #175

Open
BastiaanOlij opened this issue Aug 21, 2018 · 12 comments
Labels
bug This has been identified as a bug

Comments

@BastiaanOlij
Copy link
Collaborator

I'm probably stretching the possibilities of time and space here but I'm trying to get access to the physics engine inside of a resource.

So I have the following code:

			printf("Procedural mesh raycast, obtaining local scene\n");
			Node * localscene = get_local_scene();
			if (localscene == NULL) {
				printf("Procedural mesh raycast, no local scene found, is this a local resource?\n");
				return false;
			};
			printf("Procedural mesh raycast, obtaining viewport\n");
			Viewport * vp = localscene->get_viewport();
			if (vp == NULL) {
				printf("Procedural mesh raycast, Couldn't obtain local viewport\n");
				return false;
			}
			printf("Procedural mesh raycast, obtaining world\n");
			Ref<World> world = vp->find_world();
			if (world.is_null()) {
				printf("Procedural mesh raycast, Couldn't obtain world\n");
				return false;
			}
			printf("Procedural mesh raycast, obtaining state\n");
			PhysicsDirectSpaceState * state = world->get_direct_space_state();
			if (state == NULL) {
				printf("Procedural mesh raycast, Couldn't obtain state\n");
				return false;				
			}

Which seems to crash on that final get_direct_space_state() call:

Procedural mesh raycast, obtaining local scene
Procedural mesh raycast, obtaining viewport
Procedural mesh raycast, obtaining world
Procedural mesh raycast, obtaining state
ERROR: HashMap<class StringName,void const *,struct HashMapHasherDefault,struct HashMapComparatorDefault<class StringName>,3,8>::get: Condition ' !res ' is true. returned: *res
   At: c:\users\basti\development\godot3-git\core\hash_map.h:306
CrashHandlerException: Program crashed
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[0] NativeScriptLanguage::get_instance_binding_data (c:\users\basti\development\godot3-git\modules\gdnative\nativescript\nativescript.cpp:1236)
[1] NativeScriptLanguage::get_instance_binding_data (c:\users\basti\development\godot3-git\modules\gdnative\nativescript\nativescript.cpp:1236)
[2] godot_nativescript_get_instance_binding_data (c:\users\basti\development\godot3-git\modules\gdnative\nativescript\godot_nativescript.cpp:366)
[3] godot_nativescript_init
[4] godot_nativescript_init
[5] godot_nativescript_init
[6] godot_nativescript_init
[7] godot_nativescript_init
[8] godot_nativescript_init
[9] godot_nativescript_init
[10] godot_nativescript_init
[11] godot_nativescript_init
[12] NativeScriptInstance::call (c:\users\basti\development\godot3-git\modules\gdnative\nativescript\nativescript.cpp:736)
[13] Object::call (c:\users\basti\development\godot3-git\core\object.cpp:947)
[14] MessageQueue::_call_function (c:\users\basti\development\godot3-git\core\message_queue.cpp:260)
[15] MessageQueue::flush (c:\users\basti\development\godot3-git\core\message_queue.cpp:307)
[16] SceneTree::iteration (c:\users\basti\development\godot3-git\scene\main\scene_tree.cpp:477)
[17] Main::iteration (c:\users\basti\development\godot3-git\main\main.cpp:1777)
[18] OS_Windows::run (c:\users\basti\development\godot3-git\platform\windows\os_windows.cpp:2605)
[19] widechar_main (c:\users\basti\development\godot3-git\platform\windows\godot_win.cpp:150)
[20] _main (c:\users\basti\development\godot3-git\platform\windows\godot_win.cpp:172)
[21] main (c:\users\basti\development\godot3-git\platform\windows\godot_win.cpp:184)
[22] __scrt_common_main_seh (f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:283)
[23] BaseThreadInitThunk
-- END OF BACKTRACE --

Not sure why...

@SG7
Copy link

SG7 commented Aug 21, 2018

This is unrelated, but instead of

			Ref<World> world = vp->find_world();
			if (world.is_null()) {

to increase the protection maybe:

			Ref<World> world = vp->find_world();
			if (world == NULL || !(vp->find_world().is_valid())) {

@karroffel
Copy link
Contributor

world is not a pointer, so world == NULL won't do anything useful.

I think it might be a problem with classes not being added to the typemap properly? The error is in Godot in a HashMap lookup.

@marcelofg55
Copy link
Contributor

I've also stumbled upon this problem, it used to work fine on nativescript-1.0 for me with this code:
Physics2DDirectSpaceState *space_state = get_world_2d()->get_direct_space_state();
Now with the exact same code I'm getting a crash on the get_direct_space_state call.

@BastiaanOlij BastiaanOlij added the bug This has been identified as a bug label Nov 23, 2018
@BastiaanOlij
Copy link
Collaborator Author

I'll have to retest this, might have been fixed upstream :)

@m4nu3lf
Copy link

m4nu3lf commented Dec 1, 2018

Could this be linked to a crash I'm experiencing when trying to bind _integrate_forces() in a GDNative script inheriting from RigidBody?

[1] /usr/lib/libc.so.6(+0x37e00) [0x7fd345137e00] (??:0)
[2] NativeScriptLanguage::get_instance_binding_data(int, Object*) (??:0)
[3] ./Game(godot_nativescript_get_instance_binding_data+0x28) [0x557830304c37] (??:0)
[4] godot_variant godot::__wrapped_method<godot::RigidPart, void, godot::PhysicsDirectBodyState*>(void*, void*, void*, int, godot_variant**) (??:0)
[5] NativeScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) (??:0)
[6] ScriptInstance::call(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) (??:0)
[7] RigidBody::_direct_state_changed(Object*) (??:0)

@m4nu3lf
Copy link

m4nu3lf commented Dec 16, 2018

Any updates on this? This seem to still be an issue, I saw some updates on the related Godot issue godotengine/godot#17401

@Acclution
Copy link
Contributor

I seem to get this also. It crashes at HashMap::get function because it could not get the correct name for a class. I rigged so that it prints the names of the classes with a warning. This is my debug log:

OpenGL ES 2.0 Renderer: GeForce GTX 960M/PCIe/SSE2
WARNING: NativeScriptLanguage::get_instance_binding_data: TileSet
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: TileSet
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Viewport
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: _File
     At: modules\gdnative\nativescript\nativescript.cpp:1345
Game Start
WARNING: NativeScriptLanguage::get_instance_binding_data: CanvasLayer
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Node2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: NativeScript
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: GDNativeLibrary
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Node2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: ResourceInteractiveLoader
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Node2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: StreamTexture
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Sprite
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Physics2DShapeQueryParameters
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: RectangleShape2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: PackedScene
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: CollisionShape2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: CollisionShape2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Area2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: World2D
     At: modules\gdnative\nativescript\nativescript.cpp:1345
WARNING: NativeScriptLanguage::get_instance_binding_data: Physics2DDirectSpaceStateSW
     At: modules\gdnative\nativescript\nativescript.cpp:1345
ERROR: HashMap<class StringName,void const *,struct HashMapHasherDefault,structHashMapComparatorDefault<class StringName>,3,8>::get: Condition ' !res ' is true
. returned: *res
   At: E:\Git\godot\core/hash_map.h:306
CrashHandlerException: Program crashed
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[0] NativeScriptLanguage::get_instance_binding_data (e:\git\godot\modules\gdnative\nativescript\nativescript.cpp:1346)
[1] NativeScriptLanguage::get_instance_binding_data (e:\git\godot\modules\gdnative\nativescript\nativescript.cpp:1346)
[2] godot_nativescript_get_instance_binding_data (e:\git\godot\modules\gdnative\nativescript\godot_nativescript.cpp:366)
[3] godot::___godot_icall_Object (e:\git\godot-cpp\src\gen\__icalls.cpp:5389)
[4] godot::World2D::get_direct_space_state (e:\git\godot-cpp\src\gen\world2d.cpp:44)
[5] Acclution::Melee::Attack (e:\git\abyssofalethea\code\weapon\melee.cpp:73)
[6] Acclution::Weapon::ReleaseAttack (e:\git\abyssofalethea\code\weapon\weapon.cpp:31)
[7] Acclution::Player::ProcessWeapon (e:\git\abyssofalethea\code\entities\player.cpp:217)
[8] Acclution::Player::_Process (e:\git\abyssofalethea\code\entities\player.cpp:127)
[9] godot::_WrappedMethod<Acclution::Player,void,float>::apply<0> (e:\git\godot-cpp\include\core\godot.hpp:194)
[10] godot::__wrapped_method<Acclution::Player,void,float> (e:\git\godot-cpp\include\core\godot.hpp:210)
[11] NativeScriptInstance::call_multilevel (e:\git\godot\modules\gdnative\nativescript\nativescript.cpp:882)
[12] Node::_notification (e:\git\godot\scene\main\node.cpp:54)
[13] Node::_notificationv (e:\git\godot\scene\main\node.h:46)
[14] CanvasItem::_notificationv (e:\git\godot\scene\2d\canvas_item.h:166)
[15] Node2D::_notificationv (e:\git\godot\scene\2d\node_2d.h:38)
[16] CollisionObject2D::_notificationv (e:\git\godot\scene\2d\collision_object_2d.h:39)
[17] PhysicsBody2D::_notificationv (e:\git\godot\scene\2d\physics_body_2d.h:43)
[18] KinematicBody2D::_notificationv (e:\git\godot\scene\2d\physics_body_2d.h:290)
[19] Object::notification (e:\git\godot\core\object.cpp:957)
[20] SceneTree::_notify_group_pause (e:\git\godot\scene\main\scene_tree.cpp:969)
[21] SceneTree::idle (e:\git\godot\scene\main\scene_tree.cpp:510)
[22] Main::iteration (e:\git\godot\main\main.cpp:1865)
[23] OS_Windows::run (e:\git\godot\platform\windows\os_windows.cpp:2754)
[24] widechar_main (e:\git\godot\platform\windows\godot_win.cpp:150)
[25] _main (e:\git\godot\platform\windows\godot_win.cpp:172)
[26] main (e:\git\godot\platform\windows\godot_win.cpp:184)
[27] __scrt_common_main_seh (f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
[28] BaseThreadInitThunk
-- END OF BACKTRACE --

and as you can see Physics2DDirectSpaceState has the name Physics2DDirectSpaceStateSW but in the generated __register_types.cpp it registers with:
godot::_TagDB::register_global_type("Physics2DDirectSpaceState", typeid(Physics2DDirectSpaceState).hash_code(), typeid(Object).hash_code());

So is this a compiler quirk? I think it works fine on my linux machine (if i remember correctly).

@Acclution
Copy link
Contributor

no there seems to exist a SW implementation of physics. SoftWare or server implementation?

@Acclution
Copy link
Contributor

So I added godot::_TagDB::register_global_type("Physics2DDirectSpaceStateSW", typeid(Physics2DDirectSpaceState).hash_code(), typeid(Object).hash_code()); to __register_types.cpp and my project does not crash anymore though I do not think this is an acceptable solution in the long run?

@Acclution
Copy link
Contributor

Yea so when I call get_direct_space_state it puts the implementation of Physics2DDirectSpaceState which in my case is Physics2DDirectSpaceStateSW in a godot::Object. So when nativescript tries to get binding data it tries to get it from Physics2DDirectSpaceStateSW instead of Physics2DDirectSpaceState.

Though I do not know why it needs to call godot_nativescript_get_instance_binding_data on the data when it already has the data?

Object *___godot_icall_Object(godot_method_bind *mb, const Object *inst) {
	godot_object *ret;
	ret = nullptr;
	const void *args[1] = {
	};

	godot::api->godot_method_bind_ptrcall(mb, inst->_owner, args, &ret);
	if (ret) {
                // Why do this when ret already has the Physics2DDirectSpaceState?
		return (Object *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, ret);
	}

	return (Object *) ret;
}

@aqnuep
Copy link
Contributor

aqnuep commented Apr 11, 2019

I ran into the same issue and after some investigation and some help from @karroffel I discovered the following:

Strictly speaking this is not a binding issue, but an engine issue, as it breaks as follows:

  1. Godot does not register the implementations of the abstract classes providing the server interfaces with the ClassDB (e.g. Physics2DDirectSpaceStateSW in the above case, which implements the PhysicsDirectSpaceState abstract interface)
  2. Godot generates the JSON API information about the classes using the ClassDB, which is missing the server implementation classes
  3. As a result the JSON API file in godot_headers is missing the server implementation classes
  4. The final consequence is that the C++ bindings generate the TagDB data based on the JSON file, which again, is missing the information about the server implementation classes

The only safe solution seems to be to:

  1. Modify Godot itself to register the server implementation classes
  2. Update godot_headers with a newly generated JSON API file

After that the C++ bindings should just work.

@aqnuep
Copy link
Contributor

aqnuep commented Apr 11, 2019

Created PR godotengine/godot#27936 to fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This has been identified as a bug
Projects
None yet
7 participants