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 E7B194B2AA5; Thu, 22 Jun 2023 17:34:08 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E7B194B2AA5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1687444449; bh=QEodvMYaBogyTakN+2KHQq2YF6BwfbgZKh8Sd8yI6zQ=; 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=dWViW9n/sDFlh8/hfA5ohTczquV+uYxFplGkClbfhbsmTqF85L8fgw1/Oz1Hz9KHb N/dPEvy+YKkH3FhLYpsGEvcUhXZ1go7BUxbCzjWybhChqI0/lkDxbd6Tlm/tD8SdnZ cGJJia4zpPpIW6/Du73XajH94oBvjTJ+iBHbPEs8= Received: from smtpng3.i.mail.ru (smtpng3.i.mail.ru [94.100.177.149]) (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 8AAE74B2AA5 for ; Thu, 22 Jun 2023 17:33:39 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 8AAE74B2AA5 Received: by smtpng3.m.smailru.net with esmtpa (envelope-from ) id 1qCLNS-00053t-GW; Thu, 22 Jun 2023 17:33:39 +0300 To: Igor Munkin , Maxim Kokryashkin Date: Thu, 22 Jun 2023 17:29:18 +0300 Message-Id: <56e13650b2f5d7536c96c01bbbee3d4c42eedf67.1687439049.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: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD95D99986233CC4DDC30BBECE192AD7C83A31A99510E8D027E182A05F5380850407C1F3D72757CDF201FC5A799538AA4C7504BC5616B015E49B23ADDF9E3146506 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7F65C230EDDCD559EEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637B8A896DD3ADA3FA48638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8B645710AD9FB0194C97EC05164D6F82C117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC8C7ADC89C2F0B2A5A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F4460429728776938767073520599709FD55CB46A66FD1C55BDD38FC3FD2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B6300D3B61E77C8D3B089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: 0D63561A33F958A5C3E5AE5ED3461B9871B531DF90B25EEBB1D5BE00B4BD0D48F87CCE6106E1FC07E67D4AC08A07B9B01F9513A7CA91E5559C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF3FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CFF9DCA9995225E7F2287B532D5D4FBC4F28D008891364711898C4C3974B23BD641D17C9D1E1925344B05B57073EAFDF9726FD9A3AD5BA8E614C44189909F39875A74DFFEFA5DC0E7F02C26D483E81D6BE5EF9655DD6DEA7D65774BB76CC95456EEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojB41c+mu8Ac/1lMJLNRxEJA== X-DA7885C5: DF95E1EC7D4E55536B43AC959B5F25399EBE7C6CA2CDD46C908262A87376C9A1262E2D401490A4A0DB037EFA58388B346E8BC1A9835FDE71 X-Mailru-Sender: 689FA8AB762F73930F533AC2B33E986B740FB06A29C1334E68CFA2AEF61BCF210FBE9A32752B8C9C2AA642CC12EC09F1FB559BB5D741EB962F61BD320559CF1EFD657A8799238ED55FEEDEB644C299C0ED14614B50AE0675 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 1/2] Fix lua_yield() from C hook. 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 Reported by Jason Carr. (cherry picked from commit dd5032ed844c56964347c7916db66b0eb11d8091) When we call `lua_yield()` from the C hook the additional continuation frame is added. This frame contains a continuation function, PC where we should return, thread GC object to continue, and this frame type and size (see details in ). For non-GC64 mode, when we set the GC thread on the Lua stack, stack top isn't incremented, so the GC thread overwrites the PC to return. For the GC64 mode the increment is missing before setting frame type and size. This patches fixes the behaviour by adding missing slot incrementing. Also, it hardens the conditions of using `lj_err_throw()`, according the availability of external unwinder. The behaviour for the GC64 mode is still wrong due to miscalculation of the slot of the GC thread object. This will be fixed in the next commit. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#8516 --- src/lj_api.c | 5 +- .../fix-yield-c-hook-script.lua | 19 +++++++ .../tarantool-c-tests/fix-yield-c-hook.test.c | 53 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 test/tarantool-c-tests/fix-yield-c-hook-script.lua create mode 100644 test/tarantool-c-tests/fix-yield-c-hook.test.c diff --git a/src/lj_api.c b/src/lj_api.c index dccfe62e..89998815 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -1242,11 +1242,12 @@ LUA_API int lua_yield(lua_State *L, int nresults) setcont(top, lj_cont_hook); if (LJ_FR2) top++; setframe_pc(top, cframe_pc(cf)-1); - if (LJ_FR2) top++; + top++; setframe_gc(top, obj2gco(L), LJ_TTHREAD); + if (LJ_FR2) top++; setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT); L->top = L->base = top+1; -#if LJ_TARGET_X64 +#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS lj_err_throw(L, LUA_YIELD); #else L->cframe = NULL; diff --git a/test/tarantool-c-tests/fix-yield-c-hook-script.lua b/test/tarantool-c-tests/fix-yield-c-hook-script.lua new file mode 100644 index 00000000..124eeb10 --- /dev/null +++ b/test/tarantool-c-tests/fix-yield-c-hook-script.lua @@ -0,0 +1,19 @@ +-- Auxiliary script to provide Lua functions to be used in the +-- test . +local M = {} + +-- The function to call, when line hook (calls `lua_yield()`) is +-- set. +M.yield_in_c_hook = function() + local co = coroutine.create(function() + -- Just some payload, don't reaaly matter. + local _ = tostring(1) + end) + -- Enter coroutine and yield from the 1st line. + coroutine.resume(co) + -- Try to get the PC to return and continue to execute the first + -- line (still will yield from the hook). + coroutine.resume(co) +end + +return M diff --git a/test/tarantool-c-tests/fix-yield-c-hook.test.c b/test/tarantool-c-tests/fix-yield-c-hook.test.c new file mode 100644 index 00000000..9068360e --- /dev/null +++ b/test/tarantool-c-tests/fix-yield-c-hook.test.c @@ -0,0 +1,53 @@ +#include "lua.h" + +#include "test.h" +#include "utils.h" + +#define UNUSED(x) ((void)(x)) + +/* + * This test demonstrates LuaJIT incorrect behaviour, when calling + * `lua_yield()` inside C hook. + * See https://www.freelists.org/post/luajit/BUG-Unable-to-yield-in-a-debug-hook-in-latest-21-beta + * for details. + */ + +static lua_State *main_L = NULL; + +static void yield(lua_State *L, lua_Debug *ar) +{ + UNUSED(ar); + /* Wait for the other coroutine and yield. */ + if (L != main_L) + lua_yield(L, 0); +} + +/* + * XXX: This test still leads to core dump in the GC64 mode. + * This will be fixed in the next commit. + */ +static int yield_in_c_hook(void *test_state) +{ + lua_State *L = test_state; + utils_get_aux_lfunc(L); + lua_sethook(L, yield, LUA_MASKLINE, 0); + lua_call(L, 0, 0); + /* Remove hook. */ + lua_sethook(L, yield, 0, 0); + return TEST_EXIT_SUCCESS; +} + +int main(void) +{ + lua_State *L = utils_lua_init(); + utils_load_aux_script(L, "fix-yield-c-hook-script.lua"); + main_L = L; + + const struct test_unit tgroup[] = { + test_unit_def(yield_in_c_hook) + }; + + const int test_result = test_run_group(tgroup, L); + utils_lua_close(L); + return test_result; +} -- 2.34.1