🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

X64 GCC native CallFunction gives invalid this pointer

Started by
2 comments, last by Boost113 5 years, 9 months ago

Hi,

I have been trying to track down a crash in my game and I think I have narrowed it down to `X64_CallFunction` in `as_callfunc_x64_gcc.cpp`.

The function `CallSystemFunction` (above in the callstack) is given the object as `(void *) 0x559ee40` but when my native function is called (it is a member function) I get `(Leviathan::Physics * const) 0x565ff08` which is invalid as when I inspect the members they are garbage.

But if I try `*(Leviathan::Physics * const) 0x559ee40` that has the correct values. So AngelScript does something to the object pointer.

Additionally if I change the registration to use asCALL_GENERIC the issue goes away and my function is given the right `this` pointer. Other member functions on that type work fine. For some reason it is just this one.


    // This crashes
    if(engine->RegisterObjectMethod("Physics", "Float3 ClearVelocity() const",
           asMETHOD(Physics, ClearVelocity), asCALL_THISCALL) < 0) {
        ANGELSCRIPT_REGISTERFAIL;
    }

    // This doesn't
    // if(engine->RegisterObjectMethod("Physics", "Float3 ClearVelocity() const",
    //        WRAP_MFN(Physics, ClearVelocity), asCALL_GENERIC) < 0) {
    //     ANGELSCRIPT_REGISTERFAIL;
    // }

And here is a callstack of the crash:


0  in Leviathan::Physics::ClearVelocity() of /home/hhyyrylainen/Projects/Leviathan/Engine/Entities/Components.cpp:369
1  in X64_CallFunction of /home/hhyyrylainen/Projects/Leviathan/ThirdParty/angelscript/sdk/angelscript/source/as_callfunc_x64_gcc.cpp:74
2  in CallSystemFunctionNative of /home/hhyyrylainen/Projects/Leviathan/ThirdParty/angelscript/sdk/angelscript/source/as_callfunc_x64_gcc.cpp:468
3  in CallSystemFunction(int, asCContext*) of /home/hhyyrylainen/Projects/Leviathan/ThirdParty/angelscript/sdk/angelscript/source/as_callfunc.cpp:730
4  in asCContext::ExecuteNext of /home/hhyyrylainen/Projects/Leviathan/ThirdParty/angelscript/sdk/angelscript/source/as_context.cpp:2557
5  in asCContext::Execute() of /home/hhyyrylainen/Projects/Leviathan/ThirdParty/angelscript/sdk/angelscript/source/as_context.cpp:1324
6  in Leviathan::ScriptExecutor::RunScript<void, thrive::CellStageWorld*> of /usr/include/c++/8/ext/atomicity.h:96
7  in Leviathan::ScriptExecutor::RunScript<void, thrive::CellStageWorld*> of /home/hhyyrylainen/Projects/thrive/ThirdParty/Leviathan/Engine/Script/ScriptExecutor.h:86
8  in Leviathan::GameModule::ExecuteOnModule<void, thrive::CellStageWorld*> of /home/hhyyrylainen/Projects/thrive/ThirdParty/Leviathan/Engine/Addons/GameModule.h:63
9  in thrive::ThriveGame::startNewGame() of /home/hhyyrylainen/Projects/thrive/src/ThriveGame.cpp:329
10 in thrive::ThriveJSMessageHandler::OnProcessMessageReceived(scoped_refptr<CefBrowser>, cef_process_id_t, scoped_refptr<CefProcessMessage>) of /home/hhyyrylainen/Projects/thrive/src/thrive_js_interface.cpp:142
11 in Leviathan::GlobalCEFHandler::HandleCustomExtensionProcessMessage(scoped_refptr<CefBrowser>, cef_process_id_t, scoped_refptr<CefProcessMessage>) of /home/hhyyrylainen/Projects/Leviathan/Engine/GlobalCEFHandler.cpp:282
12 in Leviathan::GUI::View::OnProcessMessageReceived(scoped_refptr<CefBrowser>, cef_process_id_t, scoped_refptr<CefProcessMessage>) of /home/hhyyrylainen/Projects/Leviathan/Engine/GUI/GuiView.cpp:634
13 in (anonymous namespace)::client_on_process_message_received of /home/hhyyrylainen/Projects/Leviathan/ThirdParty/CEF/libcef_dll/cpptoc/client_cpptoc.cc:269
14 in OnProcessMessageReceived of ../../cef/libcef_dll/ctocpp/client_ctocpp.cc:237
15 in OnRequest of ../../cef/libcef/browser/browser_host_impl.cc:3006
16 in DispatchToMethodImpl<CefBrowserHostImpl*, void (CefBrowserHostImpl::*)(Cef_Request_Params const&), std::__1::tuple<Cef_Request_Params>, 0> of ../../base/tuple.h:52
17 in DispatchToMethod<CefBrowserHostImpl*, void (CefBrowserHostImpl::*)(Cef_Request_Params const&), std::__1::tuple<Cef_Request_Params> > of ../../base/tuple.h:60
18 in DispatchToMethod<CefBrowserHostImpl, void (CefBrowserHostImpl::*)(Cef_Request_Params const&), void, std::__1::tuple<Cef_Request_Params> > of ../../ipc/ipc_message_templates.h:51
19 in Dispatch<CefBrowserHostImpl, CefBrowserHostImpl, void, void (CefBrowserHostImpl::*)(Cef_Request_Params const&)> of ../../ipc/ipc_message_templates.h:146
20 in OnMessageReceived of ../../cef/libcef/browser/browser_host_impl.cc:2849
21 in OnMessageReceived of ../../content/browser/web_contents/web_contents_impl.cc:791
22 in OnMessageReceived of ../../content/browser/renderer_host/render_view_host_impl.cc:739
23 in OnMessageReceived of ../../content/browser/renderer_host/render_widget_host_impl.cc:594
24 in OnDispatchMessage of ../../ipc/ipc_channel_proxy.cc:320
25 in Run of ../../base/callback.h:65
26 in RunTask of ../../base/debug/task_annotator.cc:55
27 in RunTask of ../../base/message_loop/message_loop.cc:399
28 in DeferOrRunPendingTask of ../../base/message_loop/message_loop.cc:411
29 in DoWork of ../../base/message_loop/message_loop.cc:455
30 in base::MessagePumpGlib::Run(base::MessagePump::Delegate*) of ../../base/message_loop/message_pump_glib.cc:309
31 in Run of ../../base/run_loop.cc:130
32 in RunUntilIdle of ../../base/run_loop.cc:143
33 in CefBrowserMessageLoop::DoMessageLoopIteration() of ../../cef/libcef/browser/browser_message_loop.cc:116
34 in Leviathan::GlobalCEFHandler::DoCEFMessageLoopWork() of /home/hhyyrylainen/Projects/Leviathan/Engine/GlobalCEFHandler.cpp:181
35 in Leviathan::Engine::MessagePump() of /home/hhyyrylainen/Projects/Leviathan/Engine/Engine.cpp:657
36 in Leviathan::LeviathanApplication::RunMessageLoop() of /home/hhyyrylainen/Projects/Leviathan/Engine/Application/Application.cpp:124
37 in main of /home/hhyyrylainen/Projects/thrive/src/main.cpp:219
38 in __libc_start_main of /lib64/libc.so.6
39 in _start of /home/hhyyrylainen/Projects/thrive/src/main.cpp:172

I am using svn revision 2547 (I used 2482 before but I just updated to confirm that this hasn't been fixed). My compiler is 'gcc (GCC) 8.1.1 20180712 (Red Hat 8.1.1-5)'

This issue also seems to be Linux specific as other people also working on the same game on Windows don't have a crash in this function (I haven't personally tested on Windows).

I can provide a core dump of the invalid passed this pointer if that would help.

Advertisement

Most likely the problem is with how you've registered the Float3 type. Can you show me how you've registered it? Just the call the RegisterObjectType is needed. I also want to see the C++ declaration of this class so I can verify if the registration is correct.

Even without seeing your code I would risk a guess and say that it should be registered like this:


engine->RegisterObjectType("Float3", sizeof(Float3), 
	asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<vec3>() | 
	asOBJ_APP_CLASS_ALLFLOATS);

The last flag, asOBJ_APP_CLASS_ALLFLOATS, is probably what you're missing in your code.

This flag has no effect on Windows, as the C++ ABI on Windows doesn't change with the members of the classes, but with gnuc on Linux it makes a difference, which is why I believe this is the cause of your problem.

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Oh my god, I'm blind. The method actually has a return type of 'void' not 'Float3'. I guess this is what I get for copy-pasting the method registrations and forgetting to check the return types.

This is the correct binding:


    if(engine->RegisterObjectMethod("Physics", "void ClearVelocity() const",
           asMETHOD(Physics, ClearVelocity), asCALL_THISCALL) < 0) {
        ANGELSCRIPT_REGISTERFAIL;
    }

Thank you for the help.

This topic is closed to new replies.

Advertisement