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 8C8636EC55; Tue, 20 Jul 2021 15:53:28 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 8C8636EC55 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1626785608; bh=CDORjTo3r/rbYf9bd6owmyKSb+7U9xmORXFJiVrTfQg=; h=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=YLAsNLbp6FzhzY6xtKlVkkF2au5okz9el1ik7iMYXpLdKORd4bMJ761b37EKLoYTg mCKa+S/d3fRu3T9MK8vKnAFBHxREU+xnVRGFucuSCBn05n4pVUMJVR/Rnx17AMn983 SCn5odd47a81jsQNoy1/ZOL191kHYJi4j73Wf7Hk= Received: from smtpng2.i.mail.ru (smtpng2.i.mail.ru [94.100.179.3]) (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 330CF6EC55 for ; Tue, 20 Jul 2021 15:53:27 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 330CF6EC55 Received: by smtpng2.m.smailru.net with esmtpa (envelope-from ) id 1m5pFW-0000EC-3j; Tue, 20 Jul 2021 15:53:26 +0300 Date: Tue, 20 Jul 2021 15:29:52 +0300 To: Sergey Kaplun Message-ID: <20210720122952.GH11494@tarantool.org> References: <20210618062234.871-1-skaplun@tarantool.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20210618062234.871-1-skaplun@tarantool.org> X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.10.1 (2018-07-13) X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD941C43E597735A9C3038391AAE5FBFA76FBCFDED1455B43CD182A05F53808504042D58055BB70161BAF8316F483BC07E79839C9F550E22B0980FD7F8CA90D1D82 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE79A2E61952DECAF71EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637416EC277BB71E4518638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8DFECB99AAB8CF9142420EFD54A4E9EB6117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BF1175FABE1C0F9B6A471835C12D1D977C4224003CC8364762BB6847A3DEAEFB0F43C7A68FF6260569E8FC8737B5C2249EC8D19AE6D49635B68655334FD4449CB9ECD01F8117BC8BEAAAE862A0553A39223F8577A6DFFEA7CC415C329B279CF9D43847C11F186F3C59DAA53EE0834AAEE X-C1DE0DAB: 0D63561A33F958A51CDAD014E658F4D06670F04AACEC6681DDFE69BF5BF427BFD59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA7501A9DF589746230F410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34E229BE567979C940D23BE828A35B3B3FA4181FE1C14F8E3A443F0743317CCF4F9B9EE61983B234F21D7E09C32AA3244C243AC68B7221AD75CF05C952FA546DE51E098CBE561D6343927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojL49Xu4qyFBnnfD3P2+PAdg== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5D56136CD117A6EA7DCFC108432D473B91A7C8D0F45F857DBFE9F1EFEE2F478337FB559BB5D741EB964C8C2C849690F8E70A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit v1] tools: fix luajit-gdb stack dump 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: Igor Munkin via Tarantool-patches Reply-To: Igor Munkin Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Sergey, Thanks for the patch! Nice catch, actually! I wonder, how much impact this bug made while digging the crash reports. Anyway, LGTM, but consider several nits below. On 18.06.21, Sergey Kaplun wrote: > When there is only one frame (so-called dummy frame) with a dummy thread > on stack bottom at L->base - 1 - LJ_FR2, stack dump does not show stack > slots from bottom to top, because the frame link is already pointed to > stack bottom (dummy thread mentioned above). Its output looks like the Too much information in a single sentence. I consider the following info vital to understand the patch. * Dummy frame is the particular and kinda "initial" coroutine state, when the framelink slot (i.e. L->base - (1 + LJ_FR2)) is the most bottom slot of the guest stack (i.e. L->stack). * Since coroutine stack unwinding is implemented via precondition loop, no slots are dumped from L->top to L->base in case when only dummy frame is on the stack. * Python is a crap language, and seems like postcondition loop violates The Zen (this is too hard for users, isn't it?), so Guido decided not to introduce such construction in the language at all. #ifdef offtop I dare to guess, it was just too hard to distinguish precondition from postcondition in "colon&spaces" paradigm; glad Larry Wall decided to use braces for blocks, and Roberto just left Pascalish syntax for this. I'm upset with the GDB guys choice every time we're back to developing this extension. #endif comment.yield() > following: > > | 0x7fb512ac40:0x7fb512ac70 [ ] 7 slots: Red zone > | 0x7fb512ac38 [ M] > | 0x7fb512ab28:0x7fb512ac30 [ ] 34 slots: Free stack slots > | 0x7fb512ab20 [ T ] > | 0x7fb512ab08:0x7fb512ab10 [S ] FRAME: dummy L Minor: I guess, you can align the output. At least I see no reason not to do this. > comment.resume() Hence, there is no other option except unroll the first iteration and reorder stack slots dump with moving framelinks downwards to the coroutine stack bottom. > This patch unrolled first loop iteration. Stack dump first inspect all > fields for the top frame and then continue if there are other frames. > After patch the output looks like the following: > > | 0x7fb512ac40:0x7fb512ac70 [ ] 7 slots: Red zone > | 0x7fb512ac38 [ M] > | 0x7fb512ab28:0x7fb512ac30 [ ] 34 slots: Free stack slots > | 0x7fb512ab20 [ T ] > | 0x7fb512ab18 [ ] VALUE: string 0 "/tmp/net_box.lua:6: err in ser" @ 0x7fb512ade8 > | 0x7fb512ab10 [ B ] VALUE: table @ 0x7fb512ac80 (asize: 0, hmask: 0x0) > | 0x7fb512ab00:0x7fb512ab08 [S ] FRAME: dummy L Feel free to align the output here too. > --- > > Branch: https://github.com/tarantool/luajit/tree/skaplun/fix-luajit-gdb > > Steps to test behaviour: > 0) Clone branch > 1) Build tarantool with GC64 or not (I've tested both cases) > 2) Run the following script by Tarantool via gdb. > > | $ cat /tmp/netbox.lua > | box.cfg{log_level = 50, listen = "127.0.0.1:3802"} > | box.schema.user.grant('guest','read,write,execute','universe', nil, {if_not_exists=true}) > | local net_box = require"net.box" > | local cn = net_box:connect("127.0.0.1:3802") > | local function f() > | return setmetatable({}, {__serialize = function() error[[err in ser]] end}) > | end > | _G.f = f > | local r, st = cn:call("f") > | print(r,st) > > | $ gdb --args ./tarantool /tmp/netbox.lua > | ... > | (gdb) source ~/builds_workspace/luajit/fix-luajit-gdb/src/luajit-gdb.py > | ... > > 3) Set breakpoint to ./src/lua/msgpack.c:234, and run > > | (gdb) b ./src/lua/msgpack.c:234 > > I'm not sure about your sources version, so you can just set breakpoin to > mp_encode(), run and continue (need two entries). We are interested in > the line #234: > > | 233|.......if (luaL_tofield(L, cfg, opts, lua_gettop(L), &field) < 0) > | 234|.......|.......return luaT_error(L); > > And dump the stack: > > | (gdb) lj-stack L > | 0x7fb512ac40:0x7fb512ac70 [ ] 7 slots: Red zone > | 0x7fb512ac38 [ M] > | 0x7fb512ab28:0x7fb512ac30 [ ] 34 slots: Free stack slots > | 0x7fb512ab20 [ T ] > | 0x7fb512ab18 [ ] VALUE: string 0 "/tmp/net_box.lua:6: err in ser" @ 0x7fb512ade8 > | 0x7fb512ab10 [ B ] VALUE: table @ 0x7fb512ac80 (asize: 0, hmask: 0x0) > | 0x7fb512ab00:0x7fb512ab08 [S ] FRAME: dummy L > > src/luajit-gdb.py | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/src/luajit-gdb.py b/src/luajit-gdb.py > index f1fd6230..a3dad585 100644 > --- a/src/luajit-gdb.py > +++ b/src/luajit-gdb.py > @@ -424,16 +424,26 @@ def dump_stack(L, base=None, top=None): > ) > ]) + '\n' > > + # Set framelink for the top frame. Dump frame slots even for dummy frame. It would be also great to drop a few words why the iteration is unrolled (the lack of postcondition loops in Python) via XXX comment. > slot = top - 1 > framelink = base - (1 + LJ_FR2) I suggest to split this part into two blocks via blank line: * variable initialization * unrolled iteration > + while slot > framelink + LJ_FR2: > + dump += dump_stack_slot(L, slot, base, top) > + slot -= 1 > > + # If there are other frames -- continue. Again, this is not the particular reason. As for me the main reason you can't implement stack unwinding via do-while construction. > while framelink > mref('TValue *', L['stack']): > - while slot > framelink + LJ_FR2: > - dump += dump_stack_slot(L, slot, base, top) > - slot -= 1 > + assert slot == framelink + LJ_FR2, "Invalid slot during frame unwind" Please, use parentheses for assert call. > dump += dump_framelink(L, framelink) > framelink = frame_prev(framelink + LJ_FR2) - LJ_FR2 > slot -= 1 + LJ_FR2 > + while slot > framelink + LJ_FR2: > + dump += dump_stack_slot(L, slot, base, top) > + slot -= 1 > + > + assert slot == framelink + LJ_FR2, "Invalid slot after frame unwind" Ditto. > + # Skip nil slot for the last frame for 2-slot frames. > + slot -= LJ_FR2 > > dump += '{fr}{padding} [S ] FRAME: dummy L'.format( > fr = slot, > -- > 2.31.0 > -- Best regards, IM