From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 112E26ECCC; Sun, 31 Jul 2022 14:02:01 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 112E26ECCC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1659265321; bh=rv2tVS7ZEskk5Ze9i6tTwTxQdmUjbaTEnAhunbmMcWc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=cujVu/v8OAnhZVaKNkK0MlBRQICnAnmrQ5epTZ+5M3NcVHhUYqQQbMYfrzKJSScJN R2EwHTSClpekMXkGbl0fVlDIDP03OBVH1gtqi5VzZI4PQ0UflPkgkg1LKyYyPU/upz NNfMdzvQaDkIx7YSxW89G+cQZiP5kh/LyOF4IVSY= Received: from smtp42.i.mail.ru (smtp42.i.mail.ru [94.100.177.102]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id EB9B96ECCF for ; Sun, 31 Jul 2022 14:01:02 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org EB9B96ECCF Received: by smtp42.i.mail.ru with esmtpa (envelope-from ) id 1oI6gv-0008UN-WE; Sun, 31 Jul 2022 14:01:02 +0300 To: Sergey Ostanevich , Igor Munkin Date: Sun, 31 Jul 2022 13:58:31 +0300 Message-Id: <54b6d24e217454e632c9a0e8dbf29dee1c37601a.1659264154.git.skaplun@tarantool.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 78E4E2B564C1792B X-77F55803: 4F1203BC0FB41BD9626C4810127D41074D864D2C0D0E052EA834BDF88378A2F7182A05F53808504048733EF284B94A3BA3CB688A0F07C615F5B6F049DF4F479D9907672E24648AE2 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7364F8074C6DFACE2C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE7AE0F15972A9DD0A8EA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38B8859CA687ABA27BA818C63D0493291726A6EEB23C35B7056CC7F00164DA146DAFE8445B8C89999728AA50765F7900637CFE05210CFCCB54F389733CBF5DBD5E9C8A9BA7A39EFB766F5D81C698A659EA7CC7F00164DA146DA9985D098DBDEAEC82FFDA4F57982C5F4F6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA73AA81AA40904B5D9A18204E546F3947C4A7E03851CBA29566136E347CC761E074AD6D5ED66289B52698AB9A7B718F8C46E0066C2D8992A16725E5C173C3A84C30D314263C6C1DDFDBA3038C0950A5D36B5C8C57E37DE458B0BC6067A898B09E46D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE73E83C7918AC8AAC8731C566533BA786AA5CC5B56E945C8DA X-B7AD71C0: 1B70FBA5C9BEEE72C9761FC34675ADEB3023BF6BF2CA23EE09017B230C6DD59FAE9D36C4F12B34E8ED5FDC826528803AA38DF4517E1600E72FF859B6341F5BF4ED5FDC826528803A431E325DF210019CE8F7B195E1C978312EA4EECEA4A47BF0778C2F04FB368B36 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C4F3D9923D2ACB1A8F9C2B6934AE262D3EE7EAB7254005DCEDF0D475946E1DA920307CAA32FF2185809B071A32A79DF4F90BBB3A167846B176E498B0A423F6B674EA2342758AE768C2AA817B2FB80CBF9EDBE8DEE28BC9005CCEC15DA3DDAC97276791A85E4603CDE277F5FE8314FA10C5D24924BFF2A048F79C2B6934AE262D3EE7EAB7254005DCED1C39E39C5FB3188C4EAF44D9B582CE87C8A4C02DF684249C42578FD4EBC74EEF699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34047E322BFAFD69BD37F80ADF146D2ECF191287EA118D0DF10A73331F7F12EB48DDB49DFE520F4B3E1D7E09C32AA3244C5E98D639C3B8A296B0FB40DDA3F7E8A0F522A1CF68F4BE05927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojW6ri1/dK1UYkhfhKz3zvWQ== X-Mailru-Sender: 07FBBCF39629D1142254247A6196FF9BFEC69AF19772625CA3CB688A0F07C61552685D71546B8E9EDEDBA653FF35249392D99EB8CC7091A70E183A470755BFD208F19895AA18418972D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 2/2] Call error function on rethrow after trace exit. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Kaplun via Tarantool-patches Reply-To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mike Pall (cherry picked from commit e296f56b825c688c3530a981dc6b495d972f3d01) This commit changes usage of `lj_err_throw` to `lj_err_run()` in `lj_vm_exit_interp()` for not GC64 VMs, so the corresponding error handler for `xpcall()` is called after trace exit. It allows to avoid calling of error handler, when restoration from a snapshot is failed due to the Lua stack overflow. This type of error can be handled by the compiler itself and user shouldn't worry/know about them. Also, this makes behaviour and code base for GC64 and not GC64 VMs consistent. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#7230 --- The test for this patch is very fragile: if the Lua stack layout is changed (for example smbd adds a one more parameter in `luaT_call()`) the test will fail as far as some error not during snapshot restoration will raised. So this particular test is skipped for the Tarantool. Also, it is skipped for *BSD as far as there are no traces compiled [1], so there is no restoration from a snapshot, so the errfunc is called. [1]: https://github.com/tarantool/tarantool/issues/4819 src/lj_debug.c | 1 + src/lj_dispatch.h | 2 +- src/lj_err.c | 2 +- src/lj_err.h | 2 +- src/lj_trace.c | 4 ++-- src/vm_arm.dasc | 3 +-- src/vm_mips.dasc | 5 ++-- src/vm_ppc.dasc | 3 +-- src/vm_x86.dasc | 4 +--- .../lj-603-err-snap-restore.test.lua | 23 ++++++++++++++++++- 10 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/lj_debug.c b/src/lj_debug.c index 8eb5983b..654dc913 100644 --- a/src/lj_debug.c +++ b/src/lj_debug.c @@ -93,6 +93,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe) } } ins = cframe_pc(cf); + if (!ins) return NO_BCPOS; } } pt = funcproto(fn); diff --git a/src/lj_dispatch.h b/src/lj_dispatch.h index 5bda51a2..addf5572 100644 --- a/src/lj_dispatch.h +++ b/src/lj_dispatch.h @@ -46,7 +46,7 @@ extern double __divdf3(double a, double b); _(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \ _(pow) _(fmod) _(ldexp) _(lj_vm_modi) \ _(lj_dispatch_call) _(lj_dispatch_ins) _(lj_dispatch_stitch) \ - _(lj_dispatch_profile) _(lj_err_throw) \ + _(lj_dispatch_profile) _(lj_err_throw) _(lj_err_run) \ _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \ _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \ _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \ diff --git a/src/lj_err.c b/src/lj_err.c index b520b3d3..c310daf6 100644 --- a/src/lj_err.c +++ b/src/lj_err.c @@ -602,7 +602,7 @@ static ptrdiff_t finderrfunc(lua_State *L) } /* Runtime error. */ -LJ_NOINLINE void lj_err_run(lua_State *L) +LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L) { ptrdiff_t ef = finderrfunc(L); if (ef) { diff --git a/src/lj_err.h b/src/lj_err.h index cba5fb71..aa4b7e0d 100644 --- a/src/lj_err.h +++ b/src/lj_err.h @@ -23,7 +23,7 @@ LJ_DATA const char *lj_err_allmsg; LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em); LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode); LJ_FUNC_NORET void lj_err_mem(lua_State *L); -LJ_FUNC_NORET void lj_err_run(lua_State *L); +LJ_FUNCA_NORET void LJ_FASTCALL lj_err_run(lua_State *L); LJ_FUNC_NORET void lj_err_msg(lua_State *L, ErrMsg em); LJ_FUNC_NORET void lj_err_lex(lua_State *L, GCstr *src, const char *tok, BCLine line, ErrMsg em, va_list argp); diff --git a/src/lj_trace.c b/src/lj_trace.c index 68a657a7..bae4ba14 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -802,8 +802,8 @@ typedef struct ExitDataCP { static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud) { ExitDataCP *exd = (ExitDataCP *)ud; - cframe_errfunc(L->cframe) = -1; /* Inherit error function. */ - /* Always catch error here. */ + /* Always catch error here and don't call error function. */ + cframe_errfunc(L->cframe) = 0; cframe_nres(L->cframe) = -2*LUAI_MAXSTACK*(int)sizeof(TValue); exd->pc = lj_snap_restore(exd->J, exd->exptr); UNUSED(dummy); diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 21f7fecb..a29292f1 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc @@ -2247,9 +2247,8 @@ static void build_subroutines(BuildCtx *ctx) | b <2 | |9: // Rethrow error from the right C frame. - | rsb CARG2, CARG1, #0 | mov CARG1, L - | bl extern lj_err_throw // (lua_State *L, int errcode) + | bl extern lj_err_run // (lua_State *L) |.endif | |//----------------------------------------------------------------------- diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc index ec57d789..93c772ff 100644 --- a/src/vm_mips.dasc +++ b/src/vm_mips.dasc @@ -2512,9 +2512,8 @@ static void build_subroutines(BuildCtx *ctx) |. addu RA, RA, BASE | |9: // Rethrow error from the right C frame. - | load_got lj_err_throw - | negu CARG2, CRET1 - | call_intern lj_err_throw // (lua_State *L, int errcode) + | load_got lj_err_run + | call_intern lj_err_run // (lua_State *L) |. move CARG1, L |.endif | diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index 3f48b7ff..980176a2 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc @@ -2707,9 +2707,8 @@ static void build_subroutines(BuildCtx *ctx) | bctr | |9: // Rethrow error from the right C frame. - | neg CARG2, CARG1 | mr CARG1, L - | bl extern lj_err_throw // (lua_State *L, int errcode) + | bl extern lj_err_run // (lua_State *L) |.endif | |//----------------------------------------------------------------------- diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index 92140cec..22f69edf 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc @@ -3040,10 +3040,8 @@ static void build_subroutines(BuildCtx *ctx) | jmp <2 | |9: // Rethrow error from the right C frame. - | neg RD | mov FCARG1, L:RB - | mov FCARG2, RD - | call extern lj_err_throw@8 // (lua_State *L, int errcode) + | call extern lj_err_run@4 // (lua_State *L) |.endif | |//----------------------------------------------------------------------- diff --git a/test/tarantool-tests/lj-603-err-snap-restore.test.lua b/test/tarantool-tests/lj-603-err-snap-restore.test.lua index 82ce6a8f..5cb487c3 100644 --- a/test/tarantool-tests/lj-603-err-snap-restore.test.lua +++ b/test/tarantool-tests/lj-603-err-snap-restore.test.lua @@ -4,11 +4,27 @@ local tap = require('tap') -- error is raised on restoration from the snapshot. -- See also https://github.com/LuaJIT/LuaJIT/issues/603. local test = tap.test('lj-603-err-snap-restore.test.lua') -test:plan(1) +test:plan(2) +-- XXX: This is fragile. We need a specific amount of Lua stack +-- slots is used to the error on restoration from a snapshot is +-- raised and error handler isn't called according to the new +-- behaviour. With another amount of used stack slots another one +-- error may be raised (`LJ_ERR_STKOV` ("stack overflow") during +-- growing stack while trying to push error message, +-- `LJ_ERR_ERRERR` ("error in error handling"), etc.). +-- This amount is suited well for GC64 and not GC64 mode. +-- luacheck: no unused +local _, _, _, _, _, _ + +local handler_is_called = false local recursive_f local function errfunc() xpcall(recursive_f, errfunc) + -- Since this error is occured on snapshot restoration and may + -- handled by compiler itself, we shouldn't bother a user with + -- it. + handler_is_called = true end -- A recursive call to itself leads to trace with up-recursion. @@ -22,6 +38,11 @@ end recursive_f() test:ok(true) +-- Disabled on *BSD due to #4819. +-- XXX: The different amount of stack slots is in-use for +-- Tarantool at start, so just skip test for it. +-- luacheck: no global +test:ok(jit.os == 'BSD' or _TARANTOOL or not handler_is_called) -- XXX: Don't use `os.exit()` here intense. When error on snap -- restoration is raised, `err_unwind()` doesn't stop on correct -- 2.34.1