-
Notifications
You must be signed in to change notification settings - Fork 164
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
C stack overflow in error handler #24
Comments
Is there any progress on this? This is kind of a big deal for long-running servers that use lua scripting for plugins (that are always loaded). If you don't have time to fix this now, could you explain where to look to fix it? |
It's pretty complicated, the root of the problem is that when luavm hits an error it will longjump all the way back to the last pcall. We can't let this happen, in general because if between the last pcall and the call to lua_error there is a go function the go runtime will eventually find out that the C stack changed under its feets and choke. |
I'm working around this now by closing and re-initializing scripts when the "C stack overflow" error is reported. I don't see any memory leakage on initial tests, so this may be acceptable. Perhaps this should be noted in the README? |
I replace lua error with my own error handler, and find no “c stack overflow”, maybe.
|
error may cause c stack overflow aarzilli/golua#24
https://github.com/navy1125/golua I'm pleasure to put a pull request if nessary |
Could you split the |
sorry ,last two commits |
There are two problems with this approach:
|
I have a fix for this issue: #70 |
@aarzilli the correct (but somewhat annoying) solution is to wrap FFI calls in both directions, with wrappers written in the foreign language that handle converting the exception-propagation mechanism appropriately. Specifically:
I believe this should ensure that the stack is always unwound appropriately, and never incorrectly done across FFI boundaries. This approach is taken by some other existing Lua embedding/binding projects. *: Or, possibly store the information about the |
As far as I can see, the only problem with error handling is the case when an error is raised from the Go side. In that case the Go stack is left unwound because of So what if we remove the panic msghandler, move the
func (L *State) PCall(nargs, nresults int) error {
r := L.pcall(nargs, nresults, 0)
if r != 0 {
msg := L.ToString(-1)
st := L.StackTrace()
L.Pop(1)
return &LuaError{r, msg, st}
}
return nil
} The "move debug = require("debug")
debug.sethook(function()
if _LUAGO_ERROR ~= nil then
local err = _LUAGO_ERROR
_LUAGO_ERROR = nil
error(err)
end
end, "r") On the client we will need to set the value of the global variable and successfully complete the call: L.Register("foo", func(L *State) int {
if !L.IsNumber(-1) {
v := L.ToString(-1) // won't handle anything other than strings, but it is just an example
L.PushString(fmt.Sprintf("oh no, %q is not a number", v))
L.SetGlobal("_LUAGO_ERROR")
}
return 0
})
L.GetGlobal("foo")
L.PushString("oops")
if err := L.PCall(1, 0); err != nil {
fmt.Println("error:", err)
} Please, correct me if I am missing something. |
When calling a lua function that errors, the C stack is not cleaned up. If the lua function is called many times, it will eventually overflow the stack. Any further calls to the error handler result in the error "error in error handling" being returned.
This is the smallest test case I could come up with to reproduce it. I'm on Linux using lua 5.1.5 and the most recent version of golua.
error.go:
error.lua:
The text was updated successfully, but these errors were encountered: