From 8b392eced35d94752ed444a7e48d7ce4b248a602 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Wed, 28 Feb 2024 21:10:29 +0300 Subject: [PATCH] Experiments in lj-881-fix-lua-concat.test.c [TMP] https://github.com/tarantool/luajit/actions/runs/12831238829/job/35781196235 ================================================================= ==765154==ERROR: LeakSanitizer: detected memory leaks Direct leak of 256 byte(s) in 1 object(s) allocated from: #0 0x496949 in realloc (/opt/actions-runner/_work/_temp/build-12831238829/test/tarantool-c-tests/lj-881-fix-lua-concat.c_test+0x496949) #1 0x4da87a in lj_mem_realloc /opt/actions-runner/_work/luajit/luajit/src/lj_gc.c:869:7 #2 0x53f2a8 in lj_ir_growtop /opt/actions-runner/_work/luajit/luajit/src/lj_ir.c:81:23 #3 0x53f5f1 in lj_ir_nextins /opt/actions-runner/_work/luajit/luajit/src/lj_iropt.h:34:40 #4 0x53f5f1 in lj_ir_emit /opt/actions-runner/_work/luajit/luajit/src/lj_ir.c:118:15 #5 0x5cc2ea in lj_record_setup /opt/actions-runner/_work/luajit/luajit/src/lj_record.c:2651:3 #6 0x5440f0 in trace_state /opt/actions-runner/_work/luajit/luajit/src/lj_trace.c:681:7 #7 0x58c045 in lj_vm_cpcall /opt/actions-runner/_work/_temp/build-12831238829/src/lj_vm.S:1262 SUMMARY: AddressSanitizer: 256 byte(s) leaked in 1 allocation(s). --- .../lj-881-fix-lua-concat.test.c | 125 ++++++++---------- 1 file changed, 53 insertions(+), 72 deletions(-) diff --git a/test/tarantool-c-tests/lj-881-fix-lua-concat.test.c b/test/tarantool-c-tests/lj-881-fix-lua-concat.test.c index f028c457af..916fb7376a 100644 --- a/test/tarantool-c-tests/lj-881-fix-lua-concat.test.c +++ b/test/tarantool-c-tests/lj-881-fix-lua-concat.test.c @@ -6,93 +6,74 @@ #include "test.h" #include "utils.h" -/* - * This test demonstrates LuaJIT's incorrect behaviour when - * calling `lua_concat()` with userdata with the __concat metamethod. - * See https://github.com/LuaJIT/LuaJIT/issues/881 for details. - */ - -#define TYPE_NAME "int" - -#define TEST_VALUE 100 -#define TOSTR(s) #s -#define CONCAT(A, B) A TOSTR(B) +static int bbb(lua_State *L) { + luaL_dostring(L, "local function varg_func(...) end return function() return varg_func() end"); + luaL_dostring(L, "repeat until nil > 1"); + return 0; +} -static int __concat(lua_State *L) -{ - const char *s = luaL_checkstring(L, 1); - int *n = (int *)luaL_checkudata(L, 2, TYPE_NAME); - /* Do non-default concatenation. */ - lua_pushfstring(L, "%s + %d", s, *n); +static int aaa(lua_State *L) { + (void)L; + luaL_dostring(L, "local function varg_func(...) end return function() return varg_func() end"); + lua_pushcfunction(L, (lua_CFunction)bbb); + lua_pcall(L, 0, 0, 0); + luaL_dostring(L, "local function varg_func(...) end return function() return varg_func() end"); return 1; } -static const luaL_Reg mt[] = { - { "__concat", __concat }, - { NULL, NULL} -}; - -static int lua_concat_testcase(void *test_state) +static void jit_attach(lua_State *L, void *cb, const char *event) { - /* Setup. */ - lua_State *L = test_state; - const int top = 4; - - /* Create metatable and put it to the Lua registry. */ - luaL_newmetatable(L, TYPE_NAME); - /* Fill metatable. */ - luaL_register(L, 0, mt); - lua_pop(L, 1); + lua_getglobal(L, "jit"); + lua_getfield(L, -1, "attach"); + lua_pushcfunction(L, (lua_CFunction)cb); + if (event != NULL) { + lua_pushstring(L, event); + } else { + lua_pushnil(L); + } + lua_pcall(L, 2, 0, 0); +} - assert_int_equal(lua_gettop(L), 0); +static int trace_cb(lua_State *L) { + (void)L; + /* is_cb_called = 1; */ + /* luaL_dostring(L, "repeat until nil > 1"); */ + /* luaL_dostring(L, "local function varg_func(...) end return function() return varg_func() end"); */ + /* luaL_dostring(L, "error()"); */ + lua_pushcfunction(L, (lua_CFunction)aaa); + lua_pcall(L, 0, 0, 0); + return 0; +} - lua_pushliteral(L, "C"); - lua_pushliteral(L, "B"); - lua_pushliteral(L, "A"); +int main(void) +{ + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + luaL_dostring(L, "jit.opt.start('hotloop=1')"); - int *n = (int *)lua_newuserdata(L, sizeof(*n)); - *n = 100; + jit_attach(L, (void *)trace_cb, "trace"); - luaL_getmetatable(L, TYPE_NAME); - lua_setmetatable(L, -2); + /* Frame with a broken Lua code. */ + luaL_dostring(L, "repeat until nil > 1"); + /* luaL_dostring(L, "local function varg_func(...) end return function() return varg_func() end"); */ - assert_int_equal(lua_gettop(L), top); + /* Frame with C function. */ + /* lua_getfield(L, LUA_GLOBALSINDEX, "print"); */ + /* lua_pcall(L, 0, 0, 0); */ - /* Test body. */ + /* lua_pushcfunction(L, (lua_CFunction)aaa); */ + /* lua_pcall(L, 0, 0, 0); */ - /* - * void lua_concat (lua_State *L, int n); - * - * Concatenates the n values at the top of the stack, - * pops them, and leaves the result at the top. If n is 1, - * the result is the single value on the stack; if n is 0, - * the result is the empty string [1]. - * - * 1. https://www.lua.org/manual/5.1/manual.html - */ + /* lua_pushcfunction(L, (lua_CFunction)bbb); */ + /* lua_pushcfunction(L, (lua_CFunction)aaa); */ + /* lua_pcall(L, 0, 0, -2); */ - /* Concatenate two elements on the top. */ - lua_concat(L, 2); + jit_attach(L, (void *)trace_cb, NULL); - const char *str = lua_tostring(L, -1); - assert_int_equal(lua_gettop(L), top - 2 + 1); - const char expected_str[] = CONCAT("A + ", TEST_VALUE); - assert_str_equal(str, expected_str); + lua_State *LL = utils_lua_init(); + utils_lua_close(LL); /* Teardown. */ lua_settop(L, 0); - - return TEST_EXIT_SUCCESS; -} - -int main(void) -{ - lua_State *L = utils_lua_init(); - const struct test_unit tgroup[] = { - test_unit_def(lua_concat_testcase), - }; - const int test_result = test_run_group(tgroup, L); - utils_lua_close(L); - - return test_result; + return 0; }