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

example/sources/dynamic_object.cpp dangerous example? #1640

Closed
Maddimax opened this issue Nov 4, 2024 · 4 comments · May be fixed by #1641
Closed

example/sources/dynamic_object.cpp dangerous example? #1640

Maddimax opened this issue Nov 4, 2024 · 4 comments · May be fixed by #1641

Comments

@Maddimax
Copy link
Contributor

Maddimax commented Nov 4, 2024

I've been using the example/sources/dynamic_object.cpp for my own custom container-like type. I'm now running into crashes in my "sol::meta_function::index" function when it tries to access the stored sol::objects after a garbage collector run a while later.
(I call lua functions in response to various user interactions).

With my limited understanding I explain the crashes as:

  • Lua calls my dynamic_set function with a usertype value
  • I store said object
  • The object in the Lua code is no longer "active" and gets marked by the garbage collector
  • Some time later the garbage collector frees the object
  • When it the calls "dynamic_get", and I return the object from my internal store, it creates a reference to something lua already released?

Do I misunderstand the way lua keeps track of objects? Can/Should the sol::object keep the lua value "alive"?

@Maddimax
Copy link
Contributor Author

Maddimax commented Nov 4, 2024

I'm getting a crash here.

Callstack:

frame #0: 0x000000015a8189d0 libLua.dylib`luaD_reallocstack(L=0x000000016a6eda78, newsize=1, raiseerror=0) at ldo.c:216:25
frame #1: 0x000000015a818ed4 libLua.dylib`luaD_growstack(L=0x000000016a6eda78, n=1, raiseerror=0) at ldo.c:261:14
frame #2: 0x000000015a80597c libLua.dylib`lua_checkstack(L=0x000000016a6eda78, n=1) at lapi.c:120:11
frame #3: 0x000000015a80b3d0 libLua.dylib`luaL_checkstack(L=0x000000016a6eda78, space=1, msg="not enough Lua stack space to push this reference value") at lauxlib.c:381:7
frame #4: 0x0000000159f2ebe0 libLua.dylib`sol::stateless_reference::push(this=0x000000016a6ef5d8, L_=0x000000016a6eda78) const at sol.hpp:10418:4
frame #5: 0x0000000159f445a8 libLua.dylib`sol::stateless_reference::copy_ref(this=0x000000016a6ef5d8, L_=0x000000016a6eda78) const at sol.hpp:10296:4
frame #6: 0x0000000159f44554 libLua.dylib`sol::basic_reference<false>::copy_ref(this=0x000000016a6ef5d8, L_=0x000000016a6eda78) const at sol.hpp:10584:32
frame #7: 0x0000000159f44508 libLua.dylib`sol::basic_reference<false>::copy_ref(this=0x000000016a6ef5d8) const at sol.hpp:10580:11
frame #8: 0x0000000159f444b4 libLua.dylib`sol::basic_reference<false>::basic_reference(this=0x000000016fdf9240, o=0x000000016a6ef5d8) at sol.hpp:10669:78
frame #9: 0x0000000159fcd8fc libLua.dylib`sol::basic_object_base<sol::basic_reference<false>>::basic_object_base(this=0x000000016fdf9240, (null)=0x000000016a6ef5d8) at sol.hpp:17052:3
frame #10: 0x0000000159fcd8c8 libLua.dylib`sol::basic_object<sol::basic_reference<false>>::basic_object(this=0x000000016fdf9240, (null)=0x000000016a6ef5d8) at sol.hpp:17119:3
frame #11: 0x000000015a327004 libLua.dylib`sol::basic_object<sol::basic_reference<false>>::basic_object(this=0x000000016fdf9240, (null)=0x000000016a6ef5d8) at sol.hpp:17119:45
frame #12: 0x000000015a2fcd24 libLua.dylib`Lua::Internal::LuaAspectContainer::dynamic_get(this=0x000000016a6ee030, key="generalSettings") at settings.cpp:31:16

image

The L looks quite "dead" to me.

@Maddimax
Copy link
Contributor Author

Maddimax commented Nov 4, 2024

It turns out the issue is that new_index is called from a coroutine. Once that coroutine is done it seems that I cannot use sol::object's anymore that originate from it. Since we store the object ...

Is that expected?

@Maddimax
Copy link
Contributor Author

Maddimax commented Nov 4, 2024

I changed my dynamic_set to:

    void dynamic_set(const std::string &key, sol::stack_object value)
    {
        // m_lua is the LuaState of the main thread
        if (value.lua_state() != m_lua.lua_state()) {
            // This pushes the reference onto the other Lua State and returns a stack reference
            // to it.
            sol::stack_reference newRef = sol::stack_reference(m_lua, value);
            dynamic_set(key, newRef);
            return;
        }
        ...

that seems to solve the issue.

@Maddimax
Copy link
Contributor Author

Maddimax commented Nov 5, 2024

Turns out there is "main_object" etc. that does what I manually did.

@Maddimax Maddimax closed this as completed Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant