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.
core: fix cur_L restoration on error throw
This change is a kind of revertion 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` within `lj_err_throw()` to the given lua_State, where the error is raised, since this is the only coroutine that can proceed later. Also, it removes unnecessary restorations of `cur_L` at C and FF exception handlers in the VM. 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 within the corresponding assert. Resolves tarantool/tarantool#6189 Relates to tarantool/tarantool#6323 Follows up tarantool/tarantool#1516
- Loading branch information
Showing
7 changed files
with
69 additions
and
4 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
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,25 @@ | ||
local libcurl = require('libcurL') | ||
local tap = require('tap') | ||
|
||
local test = tap.test('gh-6189-curL') | ||
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') | ||
cbool(true) | ||
cbool(true) | ||
|
||
pcall(libcurl.error_from_other_thread) | ||
-- 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(libcurL libcurL.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,36 @@ | ||
#include <lua.h> | ||
#include <lauxlib.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. */ | ||
return 0; | ||
} | ||
|
||
static const struct luaL_Reg libcurL[] = { | ||
{"error_from_other_thread", error_from_other_thread}, | ||
{NULL, NULL} | ||
}; | ||
|
||
LUA_API int luaopen_libcurL(lua_State *L) | ||
{ | ||
luaL_register(L, "libcurL", libcurL); | ||
return 1; | ||
} |