-
Notifications
You must be signed in to change notification settings - Fork 393
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
VM calls error handler for memory allocation errors #880
Comments
Hmm, interesting. My recollection is that the policy we have for this is:
And yeah I think the expectation is that the error message on the stack is synthesized during the call to xpcall's error function. We "pin" the error message string (LUA_MEMERRMSG) to make sure it's always resident in memory. One possibility is that we should preserve the type of error in case xpcall error handler fails - so instead of generating LUA_ERRERR, we could keep LUA_MEMERR if the handler failed with OOM? The reason why it can be beneficial for xpcall to handle OOM is that OOM may trigger due to large allocations, but there might be enough memory still left to actually process the error. |
Unfortunately it happens only after calling error handler. I agree that it's beneficial to handle OOM, but currently there is no way to figure out (in the error handler) what was the original error code. In case of
This sounds like a good solution, but would solve the problem only partially (ie. not hiding original memory error). |
Yup you're right. That's definitely a problem. Now, would it help you if that was fixed and there was an actual error message "not enough memory" on the stack? |
I think this would help. But in general, keepking -- |
Yeah, the caveat here is that needs a different interface. You are using lua_pcall presumably but that is bound to the normal Lua C stack contract - it can't smuggle an extra integer easily, other than passing it on the stack (which changes the "signature" of the error callback), and it can't put the error in the actual thread status (lua_status) because threads must only execute code in "OK" status. So for this to work we'd need a custom "C protected call" interface - maybe similar to At any rate it looks like we should fix the error message issue. That's going to improve the behavior regardless of whether luaD_pcall is used by a C host, or a Luau script. Further improvements would involve adding a new C interface and can follow later. We'll take a look at this shortly. |
@zeux maybe there is an option to add new function, let's say This would not require +1 interface. |
This would mechanically work, but that interface doesn't seem super clean and may not be future proof. That said, if you're using The only alternative to this right now that I see is just reverting to the behavior of Lua 5.x (which is to never call the handler in the first place), but that seems a little less satisfying. We can probably implement the more complete solution first, and only remove the call to error hander on OOM later if we need to. |
Something like this is what I had in mind. One problem is that lua_pcall must obscure the status in case the error handler succeeds; if that is not done (
|
One other interesting case is, what if the function fails with a regular error code, but then the error handler fails with OOM? This is subtly different from other cases in that it's not clear what error we should return, and what error code we should return. |
Alright, I've tweaked the logic to the extent it can possibly go to handle some of these corner cases carefully. A preview version of this change should land at the end of the week behind a fast flag; if that adequately solves all concerns here we can close this. Briefly, the new behavior is:
|
Thanks @zeux
This sounds reasonable. The only question I may have, is have this (OOM handling) functionality ever been used? Given that it's broken (results from handler are ignored), it's unlikely? If think hypothetically, even collecting traceback on OOM can be useless for many cases, as allocation can fail at any point (eg creating a new string), not necessary at place with largest allocation. |
Well, any script that calls The other note is that lua_pcall can be used to collect the traceback without any heap allocations if you do this entirely on C side, using lua_getinfo + assembling the call stack on the native side. This can be used to report the error to telemetry - we do something like this at Roblox, although instead of lua_pcall we use lua_resume (which leaves the error stack in tact at an error).
It will be mostly cleaned up after this change. |
* `table.sort` was improved further. It now guarentees N*log(N) time complexity in the worst case. * Fix #880 We are also working on fixing final bugs and crashes in the new type solver. On the CodeGen front we have a few things going on: * We have a smarter register allocator for the x86 JIT * We lower more instructions on arm64 * The vector constructor builtin is now translated to IR --------- Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
* `table.sort` was improved further. It now guarentees N*log(N) time complexity in the worst case. * Fix luau-lang/luau#880 We are also working on fixing final bugs and crashes in the new type solver. On the CodeGen front we have a few things going on: * We have a smarter register allocator for the x86 JIT * We lower more instructions on arm64 * The vector constructor builtin is now translated to IR --------- Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
I work on implementing memory limits for Luau in the mlua crate and noticed that the VM calls error handler (provided to
lua_pcall
) for memory allocation errors (LUA_ERRMEM
code).PUC Lua does not do this (from 5.1 doc):
In reality it triggers
LUA_ERRERR
later in the error handler (eg. when collecting traceback) which hides the originalLUA_ERRMEM
code.Also, in this case there would be no error object on top the stack (and any returned object will be overwritten with
LUA_MEMERRMSG
)The text was updated successfully, but these errors were encountered: