Question about inconsistent errmssg for the ERRMEM in the error handler.

89 views
Skip to first unread message

Sergey Kaplun

unread,
Aug 10, 2025, 6:04:36 AMAug 10
to lua-l
Hello,

According to the documentation [1]:
> LUA_ERRERR: error while running the message handler.
May be interpreted as if _any_ error is raised in the error handler.

Assume we have the following script:
| lua -e "
| local allocinject = require('allocinject')
| coroutine.wrap(function()
|   allocinject.enable()
|   local st, msg = xpcall(error, error)
|   allocinject.disable()
|   assert(not st, 'incorrect status')
|   assert(msg:match('error in ' .. 'error handling'), 'incorrect errmsg: ' .. msg)
| end)()
| "
| lua: (command line):9: (command line):8: incorrect errmsg: not enough memory
| stack traceback:
|         [C]: in ?
|         (command line):9: in main chunk
|         [C]: in ?

Where `allocinject.enable()` just sets a wrapper around the default
allocator that returns `NULL` on every allocation. The whole code of
the module is the following:

| #include "lua.h"
| #include "lauxlib.h"
|
| #undef NDEBUG
| #include <assert.h>
|
| static lua_Alloc old_allocf = NULL;
| static void *old_alloc_state = NULL;
|
| /* Function to be used instead of the default allocator. */
| static void *allocf_with_injection(void *ud, void *ptr, size_t osize,
|    size_t nsize)
| {
| assert(old_allocf != NULL);
| /* Check the specific string allocation. */
| if (osize == 0 && nsize > 0)
| return NULL;
| return old_allocf(ud, ptr, osize, nsize);
| }
|
| static int enable(lua_State *L)
| {
| assert(old_allocf == NULL);
| old_allocf = lua_getallocf(L, &old_alloc_state);
| lua_setallocf(L, allocf_with_injection, old_alloc_state);
| return 0;
| }
|
| static int disable(lua_State *L)
| {
| assert(old_allocf != NULL);
| assert(old_allocf != allocf_with_injection);
| lua_setallocf(L, old_allocf, old_alloc_state);
| old_allocf = NULL;
| old_alloc_state = NULL;
| return 0;
| }
|
| static const struct luaL_Reg allocinject[] = {
| {"enable", enable},
| {"disable", disable},
| {NULL, NULL}
| };
|
| LUA_API int luaopen_allocinject(lua_State *L)
| {
| luaL_newlib(L, allocinject);
| return 1;
| }

Due to the memory limit, the error can't be pushed on the stack (since it
can't be allocated), the only error message presumed is OOM.

It may be considered as not a very interesting case, but still it would be
nice to mention this in the documentation.

[1]: https://www.lua.org/manual/5.4/manual.html#pdf-LUA_ERRERR

Roberto Ierusalimschy

unread,
Aug 19, 2025, 4:01:52 PMAug 19
to lu...@googlegroups.com
> According to the documentation [1]:
> > LUA_ERRERR: error while running the message handler.
> May be interpreted as if _any_ error is raised in the error handler.

You are right. Actually, LUA_ERRERR is only issued when there is a
stack overflow while running the message handler. More often than
not, errors in the message handler end in a stack overflow, as each
error calls the message handler again, which raises the error again;
but that is not always the case. We will change the explanation.

-- Roberto
Reply all
Reply to author
Forward
0 new messages