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 1CAF21B77CF1; Tue, 31 Mar 2026 10:53:08 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 1CAF21B77CF1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1774943588; bh=NL1eQvm7hKnC9yYj9wHbQgPFyyBzlB92pH3HezbiD5w=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=vf+bhRJ09fUnJtLj5Xr/P2oHMd1Za6ymzTx/Hw+7E/UUuaeIt6P3D6155sLRnWv49 JS7eSjqbWJJ3jS8rdQ0Kc5PtrLphUspUjTs6Ah2dE/ARDirZIcXZPjy1dwN+CMmEhm EBNthYg5p4/XY9GaBDBBHqmrHt2cJEMY53GzrXV0= Received: from send278.i.mail.ru (send278.i.mail.ru [95.163.59.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id DE6B41BB410D for ; Tue, 31 Mar 2026 10:53:05 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org DE6B41BB410D Received: by exim-smtp-68896ccc7f-bdp66 with esmtpa (envelope-from ) id 1w7TuL-00000000Wxw-06kP; Tue, 31 Mar 2026 10:53:05 +0300 To: Sergey Bronnikov Date: Tue, 31 Mar 2026 10:54:03 +0300 Message-ID: <20260331075403.7170-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD93432C92265B16DE329C8F671A29BF62AF191A52D437DBFFD182A05F538085040E4C62DA6DE762C053DE06ABAFEAF6705C4890A475FF6C55BF36ECDC71F27313B0E2CF4D6E7A7A002 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE74FC7AD0AD96C1577EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB55337566B07F865632A72584DED9AF5058B4A0F386221E69A6DD38BCA95EDCC24C1B3154389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C06030C3405640F6718941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6D52CD31C43BF465FCC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB8D32BA5DBAC0009BE9E8FC8737B5C2249798EDED4600259DE76E601842F6C81A12EF20D2F80756B5FB606B96278B59C4276E601842F6C81A127C277FBC8AE2E8B5713130D288095B63AA81AA40904B5D99C9F4D5AE37F343AD1F44FA8B9022EA23BBE47FD9DD3FB595F5C1EE8F4F765FC72CEEB2601E22B093A03B725D353964B0B7D0EA88DDEDAC722CA9DD8327EE4930A3850AC1BE2E735D05AD665AB97B35DC4224003CC83647689D4C264860C145E X-C1DE0DAB: 0D63561A33F958A5EEF6A5AEBCBF3E145002B1117B3ED696473DAAC132C1A9D622DFD5397F446790823CB91A9FED034534781492E4B8EEADD3CF082B023A3D3CC79554A2A72441328621D336A7BC284946AD531847A6065AED8438A78DFE0A9EBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34C77DD89D51EBB774225B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D659CAAAE712C90B84B280CC1BA87BD30FA181FB1C4519A903389F7C3FF1284B1E092C93D0062B4D5AB9B8341EE9D5BE9A0A4E726F426A3D6DF8F82E541D73A735B96E2F8A8A7C8B37736536EB022892E5344C41F94D744909CECFA6C6B0C050A61A8CAF69B82BA93681CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVdx/hWl0/CTmaGt0t+g2ex8= X-Mailru-Sender: 583F1D7ACE8F49BDD951BA70C165859E366EE8862880F824582B80AE0CC32409E0CD72BB4343F57D18A3FB21D37038BEF2400F607609286E924004A7DEC283833C7120B22964430C52B393F8C72A41A84198E0F3ECE9B5443453F38A29522196 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] Avoid recording interference due to invocation of VM hooks. 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 Thanks to Sergey Kaplun. (cherry picked from commit ab834de8b6a963a83046a72b5a7751dcd6cdcff0) If the VM event contains a trace, it may cause several inconsistencies during the recording of another trace: - If there is an exit from the trace in the VM event for the 'trace start' VM event, the JIT engine converts the newly recorded trace to the "side trace". So, when this side exit is taken, the JIT returns from the VM event in the middle of another frame. - Stitching semantics are broken for the VM events due to an inconsistent frame link chain. This patch fixes these issues by forbidding stitching in the VM event and saving the context of the JIT engine at the VM event for trace start. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#12134 --- Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1429-1434-recording-interference Related issues: * https://github.com/LuaJIT/LuaJIT/issues/1429 * https://github.com/LuaJIT/LuaJIT/issues/1434 * https://github.com/tarantool/tarantool/issues/12134 src/lj_dispatch.c | 22 +++++----- src/lj_trace.c | 11 ++++- .../lj-1429-stitching-to-vm-event.test.lua | 35 ++++++++++++++++ .../lj-1434-trace-start-interference.test.lua | 40 +++++++++++++++++++ 4 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 test/tarantool-tests/lj-1429-stitching-to-vm-event.test.lua create mode 100644 test/tarantool-tests/lj-1434-trace-start-interference.test.lua diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index 431cb3c2..e5f876b1 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c @@ -523,16 +523,18 @@ out: /* Stitch a new trace. */ void LJ_FASTCALL lj_dispatch_stitch(jit_State *J, const BCIns *pc) { - ERRNO_SAVE - lua_State *L = J->L; - void *cf = cframe_raw(L->cframe); - const BCIns *oldpc = cframe_pc(cf); - setcframe_pc(cf, pc); - /* Before dispatch, have to bias PC by 1. */ - L->top = L->base + cur_topslot(curr_proto(L), pc+1, cframe_multres_n(cf)); - lj_trace_stitch(J, pc-1); /* Point to the CALL instruction. */ - setcframe_pc(cf, oldpc); - ERRNO_RESTORE + if (!(J2G(J)->hookmask & HOOK_VMEVENT)) { + ERRNO_SAVE + lua_State *L = J->L; + void *cf = cframe_raw(L->cframe); + const BCIns *oldpc = cframe_pc(cf); + setcframe_pc(cf, pc); + /* Before dispatch, have to bias PC by 1. */ + L->top = L->base + cur_topslot(curr_proto(L), pc+1, cframe_multres_n(cf)); + lj_trace_stitch(J, pc-1); /* Point to the CALL instruction. */ + setcframe_pc(cf, oldpc); + ERRNO_RESTORE + } } #endif diff --git a/src/lj_trace.c b/src/lj_trace.c index 0dfbfa9f..7ed4c588 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -459,7 +459,11 @@ static void trace_start(jit_State *J) J->ktrace = 0; setgcref(J->cur.startpt, obj2gco(J->pt)); - lj_vmevent_send(J2G(J), TRACE, + lj_vmevent_send_(J2G(J), TRACE, + TValue savetv = J2G(J)->tmptv; + TValue savetv2 = J2G(J)->tmptv2; + TraceNo parent = J->parent; + ExitNo exitno = J->exitno; setstrV(V, V->top++, lj_str_newlit(V, "start")); setintV(V->top++, traceno); setfuncV(V, V->top++, J->fn); @@ -474,6 +478,11 @@ static void trace_start(jit_State *J) setintV(V->top++, -1); } } + , + J2G(J)->tmptv = savetv; + J2G(J)->tmptv2 = savetv2; + J->parent = parent; + J->exitno = exitno; ); lj_record_setup(J); } diff --git a/test/tarantool-tests/lj-1429-stitching-to-vm-event.test.lua b/test/tarantool-tests/lj-1429-stitching-to-vm-event.test.lua new file mode 100644 index 00000000..9ad6922e --- /dev/null +++ b/test/tarantool-tests/lj-1429-stitching-to-vm-event.test.lua @@ -0,0 +1,35 @@ +local tap = require('tap') + +-- The test file to demonstrate the incorrect recording of the +-- trace when stitching in the VM event. +-- See also https://github.com/LuaJIT/LuaJIT/issues/1429. + +local test = tap.test('lj-1429-stitching-to-vm-event'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(1) + +local function always_number(val) + return tonumber(val) or 1 +end + +-- This handler leads to stitching in the VM event. +local function hdl() + always_number('') +end + +jit.opt.start('hotloop=1', 'hotexit=1') + +jit.attach(hdl, 'trace') + +coroutine.wrap(function() + always_number('') + always_number('') + always_number(0) -- Start side trace, invoke handler. + -- This breaks the recording semantics before the patch. +end)() + +test:ok(true, 'no assertion failure') + +test:done(true) diff --git a/test/tarantool-tests/lj-1434-trace-start-interference.test.lua b/test/tarantool-tests/lj-1434-trace-start-interference.test.lua new file mode 100644 index 00000000..c4dfbfdc --- /dev/null +++ b/test/tarantool-tests/lj-1434-trace-start-interference.test.lua @@ -0,0 +1,40 @@ +local tap = require('tap') + +-- The test file to demonstrate the incorrect recording of the +-- trace when facing the trace exit in the VM event (start). +-- See also https://github.com/LuaJIT/LuaJIT/issues/1434. + +local test = tap.test('lj-1434-trace-start-interference'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(1) + +local function call(self) + return self +end + +local function cb() + -- Side exit for trace 1. + call(nil) +end + +jit.opt.start('hotloop=1', 'hotexit=1'); + +jit.attach(cb, 'trace') + +coroutine.wrap(function() + for i = 1, 4 do + -- Record trace 1. + call(call(i)) + -- Start trace 2. Side exit from trace 1 in the 'trace start' + -- VM event converts the second trace to the "side trace". + -- After that the VM assertion `lj_assert_bad_for_arg_type()` + -- fails, since we return from the VM event in the middle of + -- another frame. + end +end)() + +test:ok(true, 'no assertion failure') + +test:done(true) -- 2.53.0