fix(LuaEngine): Preallocate Lua stack size in PushRefsFor to prevent reallocation during push loop#381
Open
mostlynick3 wants to merge 4 commits intoazerothcore:masterfrom
Open
fix(LuaEngine): Preallocate Lua stack size in PushRefsFor to prevent reallocation during push loop#381mostlynick3 wants to merge 4 commits intoazerothcore:masterfrom
mostlynick3 wants to merge 4 commits intoazerothcore:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses Lua stack reallocation during BindingMap::PushRefsFor, which can lead to stack corruption/crashes when a large number of hook/function refs are pushed in a loop (e.g., many registered handlers).
Changes:
- Preallocates Lua stack capacity before pushing a binding list’s function references by calling
lua_checkstack(L, list.size()).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add error log, PANIC: unprotected error in call to Lua API (stack overflow (not enough stack space to push function bindings))
Comment on lines
193
to
195
| BindingList& list = result->second; | ||
| luaL_checkstack(L, static_cast<int>(list.size()), "not enough stack space to push function bindings"); | ||
| for (auto i = list.begin(); i != list.end();) |
| return; | ||
|
|
||
| BindingList& list = result->second; | ||
| luaL_checkstack(L, static_cast<int>(list.size()), "not enough stack space to push function bindings"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I recently ran into a problem where I ended up having so many hooks (up to 50) and functions (some 100) called on player commands that I kept getting random crashes and stack corruptions. After some troubleshooting, I found out that when the Lua stack runs out of allocated space during
PushRefsFor, Lua triggersluaD_reallocstackmid-loop, moving the stack to a new memory location. This invalidates raw pointers (cl,base,k,ra) held by anyluaV_executeframe on the C stack, causing a crash.For example, this script on a clean project crashes on reaching
reload conf:Whereas with the fix, 500 loops works correctly and I can even increase it to 50 000 without any stack corruption:
The fix is a single
lua_checkstack(L, list.size())call before the push loop inPushRefsFor, preallocating enough stack space for all function refs upfront so no reallocation occurs mid-loop. Now, the stack is safe until it overflows, instead of randomly corrupting.