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

Cannot obtain PhysicsDirectSpaceState in GDNative #28574

Closed
Cygon opened this issue May 1, 2019 · 8 comments
Closed

Cannot obtain PhysicsDirectSpaceState in GDNative #28574

Cygon opened this issue May 1, 2019 · 8 comments

Comments

@Cygon
Copy link
Contributor

Cygon commented May 1, 2019

Godot version: 3.1.1 (custom build from commit f3eafce)

OS/device including version: Gentoo Linux 4.19.27, KDE 5 Plasma, NVidia proprietary drivers 418.43

Issue description:
I am trying to do a simple raycast in C++. But whatever path I take to obtain a PhysicsDirectSpaceState, it always results in a crash here:

https://github.com/godotengine/godot/blob/master/modules/gdnative/nativescript/nativescript.cpp#L1348

Assume I had a valid, non-null Ref<World> world in GDNative C++:

Attempt #1
Segfaults at above location in nativescript.cpp

godot::PhysicsDirectSpaceState *state = world->get_direct_space_state();

Attempt #2
Segfaults at above location in nativescript.cpp

godot::RID spaceId = world->get_space();
godot::PhysicsDirectSpaceState *state = (
  godot::PhysicsServer::get_singleton()->space_get_direct_state(spaceId)
);

Attempt #3
Segfaults at above location in nativescript.cpp

const static godot::String GetDirectSpaceStateMethodName = "get_direct_space_state";
if(world->has_method(GetDirectSpaceStateMethodName)) {
  godot::Variant spaceStateAsVariant = world->call(
    GetDirectSpaceStateMethodName
  );

  // Curious: the space state reports having no method "intersect_ray"
  bool isFalse = spaceStateAsVariant.has_method("intersect_ray");

  // Triggers segfault in nativescript.cpp
  godot::Object *spaceState = godot::Object::___get_from_variant(spaceStateAsVariant);
}
@Cygon
Copy link
Contributor Author

Cygon commented May 1, 2019

I've debugged into nativescript.cpp and the segfault happens in the HashMap<StringName, const void *>::get() method:

TData &get(const TKey &p_key) {
  TData *res = getptr(p_key);
  ERR_FAIL_COND_V(!res, *res); // <---- This segfaults
  return *res;
}

So it seems that the hash table simply doesn't have the key. Is ERR_FAIL_COND_V supposed to segfault instead of assert when its condition fails?

@slapin
Copy link
Contributor

slapin commented May 1, 2019

It should not segfault but the expression written there will. because you have non-null invalid pointer.
Print the value (of pointer) there, I think this is one of many GDNative bugs. Also if you do not plan to share the code I suggest just write internal engine module, it is much more predictable.

@Cygon
Copy link
Contributor Author

Cygon commented May 1, 2019

In hash_map.h, it is hitting the return NULL here in the getptr() method
https://github.com/godotengine/godot/blob/master/core/hash_map.h#L325

Then ERR_FAIL_COND_V segfaults with a plain nullptr.

godot-hashtable-physicsdirectspacestate

That this pointer of 0x7fffffffcd70 for the HashMap<StringName, const void *> instance looks a bit suspicious, but It survives the getptr() call. Maybe it's segfaulting on the return, not the check...

@slapin
Copy link
Contributor

slapin commented May 1, 2019

are you sure it is not getptr which segfaults? try adding print of res value just agter getptr line, this will work as barrier for debugger, so it will not optimize value out, so you will know if it is getptr() or macro.
Also try to print !res and *res expressions before macro to make sure it is macro and not just plain *res segfaults.

@Cygon
Copy link
Contributor Author

Cygon commented May 1, 2019

It is *res that segfaults - inside the macro. Because it's trying to print the value in its assert message. Maybe ERR_FAIL_NULL_V ought to be used instead of ERR_FAIL_COND_V here.

godot-segfault-hashmap

I think there more interesting question here is: why isn't the key (L"BulletPhysicsDirectSpaceState") in the HashMap. And is that 0x7fffffffcd70 this pointer an indication that this might only be a follow-up issue and the real bug lies somewhere else? :)

@bojidar-bg
Copy link
Contributor

bojidar-bg commented May 1, 2019

Curious: PhysicsDirectSpaceState is registered in ClassDB (as virtual), but PhysicsDirectSpaceStateSW and BulletPhysicsDirectSpaceState aren't.

@karroffel
Copy link
Contributor

Duplicate of #28195, related PR #27936

@akien-mga
Copy link
Member

Duplicate of #28195, which is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants