From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp32.i.mail.ru (smtp32.i.mail.ru [94.100.177.92]) (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 98C11469710 for ; Mon, 25 May 2020 15:06:44 +0300 (MSK) Date: Mon, 25 May 2020 15:06:33 +0300 From: Sergey Kaplun Message-ID: <20200525120633.GA16418@root> References: <20200518093748.16825-1-skaplun@tarantool.org> <20200522140530.ymb2wcory6tbi5sz@tkn_work_nb> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200522140530.ymb2wcory6tbi5sz@tkn_work_nb> Subject: Re: [Tarantool-patches] [PATCH] lua: lua_field_inspect_table without pushcfunction List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Turenko Cc: tarantool-patches@dev.tarantool.org, Vladislav Shpilevoy On 22.05.20, Alexander Turenko wrote: > On Mon, May 18, 2020 at 12:37:48PM +0300, Sergey Kaplun wrote: > > Currently on encoding table we push cfunction (lua_field_try_serialize) > > to lua stack with additional lightuserdata and table value and after > > pcall that function to avoid a raise of error. > > It is often used to catch 'not enough memory' error. Say, to avoid a > leak if some resource should be freed before reporting an error. Or when > you want to return an error instead of raising it. > > Please, look whether it was added by intention and verify that > everything still good after the patch. Hi! As far as I can tell from the code lua_field_try_serialize hasn't got any calls of lua API that can raise error about OOM or so on, exept lua_tostring and lua_pushvalue. But we have already used lua_pushvalue and lua_pushcfunction so with this patch probability of raising error is smaller (because we need less arguments to push). And lua_tolstring calls only after checking type of lua object so lj_gc_check branch is unreacheble. 504 if (!lua_isstring(L, -1)) { 505 +--- 2 lines: diag_set(LuajitError, "invalid " LUAL_SERIALIZE " value");-- 507 } 508 const char *type = lua_tostring(L, -1); 491 LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len) 492 { 493 TValue *o = index2adr(L, idx); 494 GCstr *s; 495 if (LJ_LIKELY(tvisstr(o))) { 496 s = strV(o); 497 } else if (tvisnumber(o)) { 498 lj_gc_check(L); If I understand correctly, we must avoid panic when called luaL_tofield. I was able to come up with a similar example, how to show that the behavior has not changed. But I am not 100% sure that this test covers all corner cases. Do you have any idea of a more complete test? | 13:00:04 jobs:0 burii@root:~/builds_workspace/tarantool/master$ | >>> ../no-ticket-lua-inspect-table-refactoring/src/tarantool | Tarantool 2.5.0-32-g7f20272ea | type 'help' for interactive help | tarantool> collectgarbage("stop") | local source = setmetatable({}, {__serialize = "map"}) | print("start") | for i = 1, 340000 do | table.insert(source, (tostring(i)):rep(1024)) | end | print("end") | local msgpack = require "msgpack" | return pcall(msgpack.encode, source) | start | end | --- | - false | - not enough memory | ... | | tarantool> 13:00:41 jobs:0 burii@root:~/builds_workspace/tarantool/master$ | >>> src/tarantool | Tarantool 2.5.0-1-gad13b6d57 | type 'help' for interactive help | tarantool> collectgarbage("stop") | local source = {} | print("start") | for i = 1, 340000 do | table.insert(source, (tostring(i)):rep(1024)) | end | print("end") | local msgpack = require "msgpack" | return pcall(msgpack.encode, source) | start | end | --- | - false | - not enough memory | ... -- Best regards, Sergey Kaplun