forked from LuaJIT/LuaJIT
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arm64: fix cur_L restoration on error throw
This change is the follow-up of commits ed412cd ('Update cur_L on exceptional path') and 97699d9 ('Fix cur_L tracking on exceptional path'). When an error is thrown on the coroutine that is not the one being currently executed, `cur_L` is not set up. Hence, when the running trace exits at assertion guard right after the error is caught, Lua state is restored from the incorrect `cur_L`. As a result the resulting stack is inconsistent and the crash occurs. Aforementioned patches fix the behaviour only for x86/x64 architectures. This patch updates the `cur_L` for arm64 architecture too. Nevertheless, throwing an error at non-currently executed coroutine is a violation of Lua/C API. So, in the nearest possible future this patch should be replaced with the corresponding assert in `lj_err_throw()`. Resolves tarantool/tarantool#6189 Relates to tarantool/tarantool#6323 Follows up tarantool/tarantool#1516
- Loading branch information
Showing
5 changed files
with
72 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
local libcur_L = require('libcur_L') | ||
local tap = require('tap') | ||
|
||
local test = tap.test('gh-6189-cur_L') | ||
test:plan(1) | ||
|
||
local function cbool(cond) | ||
if cond then | ||
return 1 | ||
else | ||
return 0 | ||
end | ||
end | ||
|
||
-- Compile function to trace with snapshot. | ||
jit.opt.start('hotloop=1') | ||
-- First call makes `cbool()` hot enough to be recorded next time. | ||
cbool(true) | ||
-- Second call records `cbool()` body (i.e. `if` branch). This is | ||
-- a root trace for `cbool()`. | ||
cbool(true) | ||
|
||
assert(pcall(libcur_L.error_from_other_thread) == false, "return from error") | ||
-- Call with restoration from a snapshot with wrong cur_L. | ||
cbool(false) | ||
|
||
test:ok(true) | ||
os.exit(test:check() and 0 or 1) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
BuildTestCLib(libcur_L libcur_L.c) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include <lua.h> | ||
#include <lauxlib.h> | ||
|
||
#undef NDEBUG | ||
#include <assert.h> | ||
|
||
static lua_State *old_L = NULL; | ||
|
||
int throw_error_at_old_thread(lua_State *cur_L) | ||
{ | ||
lua_error(old_L); | ||
/* Unreachable. */ | ||
return 0; | ||
} | ||
|
||
static int error_from_other_thread(lua_State *L) | ||
{ | ||
lua_State *next_cur_L = lua_newthread(L); | ||
old_L = L; | ||
/* Remove thread. */ | ||
lua_pop(L, 1); | ||
/* Do not show frame slot as return result after error. */ | ||
lua_pushnil(L); | ||
lua_pushcfunction(next_cur_L, throw_error_at_old_thread); | ||
lua_call(next_cur_L, 0, 0); | ||
/* Unreachable. */ | ||
assert(0); | ||
return 0; | ||
} | ||
|
||
static const struct luaL_Reg libcur_L[] = { | ||
{"error_from_other_thread", error_from_other_thread}, | ||
{NULL, NULL} | ||
}; | ||
|
||
LUA_API int luaopen_libcur_L(lua_State *L) | ||
{ | ||
luaL_register(L, "libcur_L", libcur_L); | ||
return 1; | ||
} |