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 83D4D562372; Thu, 3 Aug 2023 10:47:57 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 83D4D562372 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1691048877; bh=a4y5vTvIHtueXp/0YK/wqlT+QjR8bWNl1Amoo0wHcdQ=; 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=FoVl5WiP83pdBrimphoiBKFr7SH403p28NUb/P/K5qQPaovUnFIQuQRoO9PftLdI4 FCn34mDJru3zOnq3ovaemtWBAE9mT0eYV/OenWKXio+h0Ta47HK7sU4l6XA7ISFCFv GBiI0bHf93ubf+Oqfy0Ei+STW4Z1D0Q7tp1xnUSY= Received: from smtp58.i.mail.ru (smtp58.i.mail.ru [95.163.41.96]) (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 D1058562372 for ; Thu, 3 Aug 2023 10:44:02 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org D1058562372 Received: by smtp58.i.mail.ru with esmtpa (envelope-from ) id 1qRT05-000EDQ-13; Thu, 03 Aug 2023 10:44:02 +0300 To: Maxim Kokryashkin , Sergey Bronnikov Date: Thu, 3 Aug 2023 07:30:33 +0000 Message-Id: <8ee8de2f67e034c3ffb4a2d587df6ed32f349b53.1691047132.git.imun@tarantool.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD93761F2630DFFAF419FF9F365118383038215B45E24F6DA4B182A05F53808504044D90414322B19B51D0F2C323AD5539B070BED9491A1A59FE10D795F24E71B43 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE789066434B85BF7C7EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006370E2FF649BDAFCC308638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D840B04CF129244CEE05E421ADB4146496117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC974A882099E279BDA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F4460429728776938767073520CCD848CCB6FE560CBDFBBEFFF4125B51D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE26055571C92BF10FA9D86F9317F2E7ACD8FC6C240DEA76429C9F4D5AE37F343AA9539A8B242431040A6AB1C7CE11FEE324D079F6B4507B16302FCEF25BFAB345C4224003CC836476E2F48590F00D11D6E2021AF6380DFAD1A18204E546F3947C062BEEFFB5F8EA3E2E808ACE2090B5E1725E5C173C3A84C3E478A468B35FE767089D37D7C0E48F6C8AA50765F7900637EC3198ECE464ADAEEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-B7AD71C0: 4965CFDFE0519134C1FE400A9E48C5401DD40DE57556AFB266D16FC5F53507A1816E0A2A8F779BBED8D40077074E805C66D16FC5F53507A117535B0CF9F6D0C3EE9D5CB6078CC77CCE332338D80C9363EE319BF62A11F40A X-C1DE0DAB: 0D63561A33F958A50C6A23E67949431843F7D6B393291FE0C76A1C6C3344E159F87CCE6106E1FC07E67D4AC08A07B9B062B3BD3CC35DA5889C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0AD75DCE07D45A749953FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CFA6A8AD8E0E775A40FDA24F18EB1B4489F28769A8C5EC8122DB7963AA13A381B9025CA78FE36D22578553022043D0BC9ADB91074FF7D16A6743E7869FCF1BE05FA74DFFEFA5DC0E7F02C26D483E81D6BEECAEF3E2CCC1ED8C383653B6C8D9AE0FD16FCAA6493B703A X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojcir52QaMQ81k1WXGGLX2+A== X-Mailru-Sender: 2FEBA92C8E508479FE7B9A1DF348D531C55F6AC43F6B03288933CE7EECA6AF4FB5B3668FD548DDDE2326FE6F2A341ACE0FB9F97486540B4CD9E8847AB8CFED4D9ABF8A61C016C2CFB0DAF586E7D11B3E67EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 08/15] test: fix E302 errors by pycodestyle 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" Fixed 149 occurrences of E302 ("expected 2 blank lines, found 1") error reported by pycodestyle[1]. [1]: https://www.flake8rules.com/rules/E302.html Signed-off-by: Igor Munkin --- src/luajit-gdb.py | 73 ++++++++++++++++++++++++++++++++++++++++++++ src/luajit_lldb.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/src/luajit-gdb.py b/src/luajit-gdb.py index f87063f8..9c51be0b 100644 --- a/src/luajit-gdb.py +++ b/src/luajit-gdb.py @@ -18,6 +18,7 @@ if LEGACY: gtype_cache = {} + def gtype(typestr): global gtype_cache if typestr in gtype_cache: @@ -31,13 +32,16 @@ def gtype(typestr): gtype_cache[typestr] = gtype return gtype + def cast(typestr, val): return gdb.Value(val).cast(gtype(typestr)) + def lookup(symbol): variable, _ = gdb.lookup_symbol(symbol) return variable.value() if variable else None + def parse_arg(arg): if not arg: return None @@ -49,15 +53,19 @@ def parse_arg(arg): return ret + def tou64(val): return cast('uint64_t', val) & 0xFFFFFFFFFFFFFFFF + def tou32(val): return cast('uint32_t', val) & 0xFFFFFFFF + def i2notu32(val): return ~int(val) & 0xFFFFFFFF + def strx64(val): return re.sub('L?$', '', hex(int(cast('uint64_t', val) & 0xFFFFFFFFFFFFFFFF))) @@ -81,6 +89,7 @@ LJ_T = { 'NUMX': i2notu32(13), } + def typenames(value): return { LJ_T[k]: 'LJ_T' + k for k in LJ_T.keys() @@ -105,6 +114,7 @@ FRAME = { 'PCALLH': 0x7, } + def frametypes(ft): return { FRAME['LUA']: 'L', @@ -113,43 +123,55 @@ def frametypes(ft): FRAME['VARG']: 'V', }.get(ft, '?') + def bc_a(ins): return (ins >> 8) & 0xff + def frame_ftsz(framelink): return cast('ptrdiff_t', framelink['ftsz'] if LJ_FR2 \ else framelink['fr']['tp']['ftsz']) + def frame_pc(framelink): return cast('BCIns *', frame_ftsz(framelink)) if LJ_FR2 \ else mref('BCIns *', framelink['fr']['tp']['pcr']) + def frame_prevl(framelink): return framelink - (1 + LJ_FR2 + bc_a(frame_pc(framelink)[-1])) + def frame_ispcall(framelink): return (frame_ftsz(framelink) & FRAME['PCALL']) == FRAME['PCALL'] + def frame_sized(framelink): return (frame_ftsz(framelink) & ~FRAME_TYPEP) + def frame_prevd(framelink): return cast('TValue *', cast('char *', framelink) - frame_sized(framelink)) + def frame_type(framelink): return frame_ftsz(framelink) & FRAME_TYPE + def frame_typep(framelink): return frame_ftsz(framelink) & FRAME_TYPEP + def frame_islua(framelink): return frametypes(int(frame_type(framelink))) == 'L' \ and int(frame_ftsz(framelink)) > 0 + def frame_prev(framelink): return frame_prevl(framelink) if frame_islua(framelink) \ else frame_prevd(framelink) + def frame_sentinel(L): return mref('TValue *', L['stack']) + LJ_FR2 @@ -174,23 +196,29 @@ LIGHTUD_LO_MASK = (1 << LJ_LIGHTUD_BITS_LO) - 1 # }}} + def itype(o): return cast('uint32_t', o['it64'] >> 47) if LJ_GC64 else o['it'] + def mref(typename, obj): return cast(typename, obj['ptr64'] if LJ_GC64 else obj['ptr32']) + def gcref(obj): return cast('GCobj *', obj['gcptr64'] if LJ_GC64 else cast('uintptr_t', obj['gcptr32'])) + def gcval(obj): return cast('GCobj *', obj['gcptr64'] & LJ_GCVMASK if LJ_GC64 else cast('uintptr_t', obj['gcptr32'])) + def gcnext(obj): return gcref(obj)['gch']['nextgc'] + def L(L=None): # lookup a symbol for the main coroutine considering the host app # XXX Fragile: though the loop initialization looks like a crap but it @@ -205,9 +233,11 @@ def L(L=None): if l: return cast('lua_State *', l) + def G(L): return mref('global_State *', L['glref']) + def J(g): typeGG = gtype('GG_State') @@ -215,6 +245,7 @@ def J(g): - int(typeGG['g'].bitpos / 8) + int(typeGG['J'].bitpos / 8)) + def vm_state(g): return { i2notu32(0): 'INTERP', @@ -228,6 +259,7 @@ def vm_state(g): i2notu32(8): 'ASM', }.get(int(tou32(g['vmstate'])), 'TRACE') + def gc_state(g): return { 0: 'PAUSE', @@ -239,6 +271,7 @@ def gc_state(g): 6: 'LAST', }.get(int(g['gc']['state']), 'INVALID') + def jit_state(g): return { 0: 'IDLE', @@ -250,18 +283,22 @@ def jit_state(g): 0x15: 'ERR', }.get(int(J(g)['state']), 'INVALID') + def tvisint(o): return LJ_DUALNUM and itype(o) == LJ_TISNUM + def tvisnumber(o): return itype(o) <= LJ_TISNUM + def tvislightud(o): if LJ_64 and not LJ_GC64: return (cast('int32_t', itype(o)) >> 15) == -2 else: return itype(o) == LJ_T['LIGHTUD'] + def strdata(obj): # String is printed with pointer to it, thanks to gdb. Just strip it. try: @@ -269,6 +306,7 @@ def strdata(obj): except UnicodeEncodeError: return "" + def itypemap(o): if LJ_64 and not LJ_GC64: return LJ_T['NUMX'] if tvisnumber(o) \ @@ -277,12 +315,14 @@ def itypemap(o): else: return LJ_T['NUMX'] if tvisnumber(o) else itype(o) + def funcproto(func): assert(func['ffid'] == 0) return cast('GCproto *', mref('char *', func['pc']) - gdb.lookup_type('GCproto').sizeof) + def gclistlen(root, end=0x0): count = 0 while(gcref(root) != end): @@ -290,6 +330,7 @@ def gclistlen(root, end=0x0): root = gcnext(root) return count + def gcringlen(root): if not gcref(root): return 0 @@ -307,6 +348,7 @@ gclen = { 'mmudata': gcringlen, } + # The generator that implements frame iterator. # Every frame is represented as a tuple of framelink and frametop. def frames(L): @@ -320,6 +362,7 @@ def frames(L): break framelink = frame_prev(framelink) + def lightudV(tv): if LJ_64: u = int(tv['u64']) @@ -333,33 +376,42 @@ def lightudV(tv): # Dumpers {{{ + def dump_lj_tnil(tv): return 'nil' + def dump_lj_tfalse(tv): return 'false' + def dump_lj_ttrue(tv): return 'true' + def dump_lj_tlightud(tv): return 'light userdata @ {}'.format(strx64(lightudV(tv))) + def dump_lj_tstr(tv): return 'string {body} @ {address}'.format( body=strdata(gcval(tv['gcr'])), address=strx64(gcval(tv['gcr'])) ) + def dump_lj_tupval(tv): return 'upvalue @ {}'.format(strx64(gcval(tv['gcr']))) + def dump_lj_tthread(tv): return 'thread @ {}'.format(strx64(gcval(tv['gcr']))) + def dump_lj_tproto(tv): return 'proto @ {}'.format(strx64(gcval(tv['gcr']))) + def dump_lj_tfunc(tv): func = cast('struct GCfuncC *', gcval(tv['gcr'])) ffid = func['ffid'] @@ -377,6 +429,7 @@ def dump_lj_tfunc(tv): else: return 'fast function #{}'.format(int(ffid)) + def dump_lj_ttrace(tv): trace = cast('struct GCtrace *', gcval(tv['gcr'])) return 'trace {traceno} @ {addr}'.format( @@ -384,9 +437,11 @@ def dump_lj_ttrace(tv): addr=strx64(trace) ) + def dump_lj_tcdata(tv): return 'cdata @ {}'.format(strx64(gcval(tv['gcr']))) + def dump_lj_ttab(tv): table = cast('GCtab *', gcval(tv['gcr'])) return 'table @ {gcr} (asize: {asize}, hmask: {hmask})'.format( @@ -395,15 +450,18 @@ def dump_lj_ttab(tv): hmask=strx64(table['hmask']), ) + def dump_lj_tudata(tv): return 'userdata @ {}'.format(strx64(gcval(tv['gcr']))) + def dump_lj_tnumx(tv): if tvisint(tv): return 'integer {}'.format(cast('int32_t', tv['i'])) else: return 'number {}'.format(cast('double', tv['n'])) + def dump_lj_invalid(tv): return 'not valid type @ {}'.format(strx64(gcval(tv['gcr']))) @@ -426,13 +484,16 @@ dumpers = { 'LJ_TNUMX': dump_lj_tnumx, } + def dump_tvalue(tvalue): return dumpers.get(typenames(itypemap(tvalue)), dump_lj_invalid)(tvalue) + def dump_framelink_slot_address(fr): return '{}:{}'.format(fr - 1, fr) if LJ_FR2 \ else '{}'.format(fr) + PADDING + def dump_framelink(L, fr): if fr == frame_sentinel(L): return '{addr} [S ] FRAME: dummy L'.format( @@ -448,6 +509,7 @@ def dump_framelink(L, fr): f=dump_lj_tfunc(fr - LJ_FR2), ) + def dump_stack_slot(L, slot, base=None, top=None): base = base or L['base'] top = top or L['top'] @@ -461,6 +523,7 @@ def dump_stack_slot(L, slot, base=None, top=None): value=dump_tvalue(slot), ) + def dump_stack(L, base=None, top=None): base = base or L['base'] top = top or L['top'] @@ -502,6 +565,7 @@ def dump_stack(L, base=None, top=None): return '\n'.join(dump) + def dump_gc(g): gc = g['gc'] stats = ['{key}: {value}'.format(key=f, value=gc[f]) for f in ( @@ -530,6 +594,7 @@ class LJBase(gdb.Command): gdb.Command.__init__(self, name, gdb.COMMAND_DATA) gdb.write('{} command initialized\n'.format(name)) + class LJDumpArch(LJBase): ''' lj-arch @@ -549,6 +614,7 @@ pointers respectively. ) ) + class LJDumpTValue(LJBase): ''' lj-tv @@ -582,6 +648,7 @@ error message occurs. tv = cast('TValue *', parse_arg(arg)) gdb.write('{}\n'.format(dump_tvalue(tv))) + class LJDumpString(LJBase): ''' lj-str @@ -601,6 +668,7 @@ is replaced with the corresponding error when decoding fails. len=string['len'], )) + class LJDumpTable(LJBase): ''' lj-tab @@ -646,6 +714,7 @@ The command receives a GCtab adress and dumps the table contents: n=mref('struct Node *', node['next']) )) + class LJDumpStack(LJBase): ''' lj-stack [] @@ -682,6 +751,7 @@ If L is ommited the main coroutine is used. def invoke(self, arg, from_tty): gdb.write('{}\n'.format(dump_stack(L(parse_arg(arg))))) + class LJState(LJBase): ''' lj-state @@ -701,6 +771,7 @@ The command requires no args and dumps current VM and GC states }.items()) ))) + class LJGC(LJBase): ''' lj-gc @@ -727,6 +798,7 @@ The command requires no args and dumps current GC stats: stats=dump_gc(g) )) + def init(commands): global LJ_64, LJ_GC64, LJ_FR2, LJ_DUALNUM, LJ_TISNUM, PADDING @@ -783,6 +855,7 @@ def init(commands): gdb.write('luajit-gdb.py is successfully loaded\n') + def load(event=None): init({ 'lj-arch': LJDumpArch, diff --git a/src/luajit_lldb.py b/src/luajit_lldb.py index b62705c3..bd8353d5 100644 --- a/src/luajit_lldb.py +++ b/src/luajit_lldb.py @@ -21,6 +21,7 @@ LJ_TISNUM = None # Global target = None + class Ptr: def __init__(self, value, normal_type): self.value = value @@ -82,6 +83,7 @@ class Ptr: return getattr(self.__deref, name) return self.__deref + class MetaStruct(type): def __init__(cls, name, bases, nmspc): super(MetaStruct, cls).__init__(name, bases, nmspc) @@ -108,6 +110,7 @@ class MetaStruct(type): property(make_general(field[1], field[0])), ) + class Struct(metaclass=MetaStruct): def __init__(self, value): self.value = value @@ -274,6 +277,7 @@ class Command(object): automatically transformed into proper errors. """ + def cast(typename, value): pointer_type = False name = None @@ -321,31 +325,39 @@ def cast(typename, value): else: return casted + def lookup_global(name): return target.FindFirstGlobalVariable(name) + def type_member(type_obj, name): return next((x for x in type_obj.members if x.name == name), None) + def find_type(typename): return target.FindFirstType(typename) + def offsetof(typename, membername): type_obj = find_type(typename) member = type_member(type_obj, membername) assert member is not None return member.GetOffsetInBytes() + def sizeof(typename): type_obj = find_type(typename) return type_obj.GetByteSize() + def vtou64(value): return value.unsigned & 0xFFFFFFFFFFFFFFFF + def vtoi(value): return value.signed + def dbg_eval(expr): process = target.GetProcess() thread = process.GetSelectedThread() @@ -354,17 +366,21 @@ def dbg_eval(expr): # }}} Debugger specific + def gcval(obj): return cast(GCobjPtr, cast('uintptr_t', obj.gcptr & LJ_GCVMASK) if LJ_GC64 else cast('uintptr_t', obj.gcptr)) + def gcref(obj): return cast(GCobjPtr, obj.gcptr if LJ_GC64 else cast('uintptr_t', obj.gcptr)) + def gcnext(obj): return gcref(obj).gch.nextgc + def gclistlen(root, end=0x0): count = 0 while(gcref(root) != end): @@ -372,6 +388,7 @@ def gclistlen(root, end=0x0): root = gcnext(root) return count + def gcringlen(root): if not gcref(root): return 0 @@ -389,6 +406,7 @@ gclen = { 'mmudata': gcringlen, } + def dump_gc(g): gc = g.gc stats = ['{key}: {value}'.format(key=f, value=getattr(gc, f)) for f in ( @@ -407,9 +425,11 @@ def dump_gc(g): ) for stat, handler in gclen.items()] return '\n'.join(map(lambda s: '\t' + s, stats)) + def mref(typename, obj): return cast(typename, obj.ptr) + def J(g): g_offset = offsetof('GG_State', 'g') J_offset = offsetof('GG_State', 'J') @@ -418,9 +438,11 @@ def J(g): vtou64(cast('char *', g)) - g_offset + J_offset, ) + def G(L): return mref(global_StatePtr, L.glref) + def L(L=None): # lookup a symbol for the main coroutine considering the host app # XXX Fragile: though the loop initialization looks like a crap but it @@ -435,12 +457,15 @@ def L(L=None): if l: return lua_State(l) + def tou32(val): return val & 0xFFFFFFFF + def i2notu32(val): return ~int(val) & 0xFFFFFFFF + def vm_state(g): return { i2notu32(0): 'INTERP', @@ -454,6 +479,7 @@ def vm_state(g): i2notu32(8): 'ASM', }.get(int(tou32(g.vmstate)), 'TRACE') + def gc_state(g): return { 0: 'PAUSE', @@ -465,6 +491,7 @@ def gc_state(g): 6: 'LAST', }.get(g.gc.state, 'INVALID') + def jit_state(g): return { 0: 'IDLE', @@ -476,16 +503,19 @@ def jit_state(g): 0x15: 'ERR', }.get(J(g).state, 'INVALID') + def strx64(val): return re.sub('L?$', '', hex(int(val) & 0xFFFFFFFFFFFFFFFF)) + def funcproto(func): assert(func.ffid == 0) proto_size = sizeof('GCproto') value = cast('uintptr_t', vtou64(mref('char *', func.pc)) - proto_size) return cast(GCprotoPtr, value) + def strdata(obj): try: ptr = cast('char *', obj + 1) @@ -493,48 +523,61 @@ def strdata(obj): except UnicodeEncodeError: return "" + def itype(o): return tou32(o.it64 >> 47) if LJ_GC64 else o.it + def tvisint(o): return LJ_DUALNUM and itype(o) == LJ_TISNUM + def tvislightud(o): if LJ_64 and not LJ_GC64: return (vtoi(cast('int32_t', itype(o))) >> 15) == -2 else: return itype(o) == LJ_T['LIGHTUD'] + def tvisnumber(o): return itype(o) <= LJ_TISNUM + def dump_lj_tnil(tv): return 'nil' + def dump_lj_tfalse(tv): return 'false' + def dump_lj_ttrue(tv): return 'true' + def dump_lj_tlightud(tv): return 'light userdata @ {}'.format(strx64(gcval(tv.gcr))) + def dump_lj_tstr(tv): return 'string {body} @ {address}'.format( body=strdata(cast(GCstrPtr, gcval(tv.gcr))), address=strx64(gcval(tv.gcr)) ) + def dump_lj_tupval(tv): return 'upvalue @ {}'.format(strx64(gcval(tv.gcr))) + def dump_lj_tthread(tv): return 'thread @ {}'.format(strx64(gcval(tv.gcr))) + def dump_lj_tproto(tv): return 'proto @ {}'.format(strx64(gcval(tv.gcr))) + def dump_lj_tfunc(tv): func = cast(GCfuncCPtr, gcval(tv.gcr)) ffid = func.ffid @@ -552,6 +595,7 @@ def dump_lj_tfunc(tv): else: return 'fast function #{}'.format(ffid) + def dump_lj_ttrace(tv): trace = cast(GCtracePtr, gcval(tv.gcr)) return 'trace {traceno} @ {addr}'.format( @@ -559,9 +603,11 @@ def dump_lj_ttrace(tv): addr=strx64(trace) ) + def dump_lj_tcdata(tv): return 'cdata @ {}'.format(strx64(gcval(tv.gcr))) + def dump_lj_ttab(tv): table = cast(GCtabPtr, gcval(tv.gcr)) return 'table @ {gcr} (asize: {asize}, hmask: {hmask})'.format( @@ -570,15 +616,18 @@ def dump_lj_ttab(tv): hmask=strx64(table.hmask), ) + def dump_lj_tudata(tv): return 'userdata @ {}'.format(strx64(gcval(tv.gcr))) + def dump_lj_tnumx(tv): if tvisint(tv): return 'integer {}'.format(cast('int32_t', tv.i)) else: return 'number {}'.format(tv.n) + def dump_lj_invalid(tv): return 'not valid type @ {}'.format(strx64(gcval(tv.gcr))) @@ -616,6 +665,7 @@ LJ_T = { 'NUMX': i2notu32(13), } + def itypemap(o): if LJ_64 and not LJ_GC64: return LJ_T['NUMX'] if tvisnumber(o) \ @@ -623,11 +673,13 @@ def itypemap(o): else: return LJ_T['NUMX'] if tvisnumber(o) else itype(o) + def typenames(value): return { LJ_T[k]: 'LJ_T' + k for k in LJ_T.keys() }.get(int(value), 'LJ_TINVALID') + def dump_tvalue(tvptr): return dumpers.get(typenames(itypemap(tvptr)), dump_lj_invalid)(tvptr) @@ -646,6 +698,7 @@ FRAME = { 'PCALLH': 0x7, } + def frametypes(ft): return { FRAME['LUA']: 'L', @@ -654,17 +707,21 @@ def frametypes(ft): FRAME['VARG']: 'V', }.get(ft, '?') + def bc_a(ins): return (ins >> 8) & 0xff + def frame_ftsz(framelink): return vtou64(cast('ptrdiff_t', framelink.ftsz if LJ_FR2 \ else framelink.fr.tp.ftsz)) + def frame_pc(framelink): return cast(BCInsPtr, frame_ftsz(framelink)) if LJ_FR2 \ else mref(BCInsPtr, framelink.fr.tp.pcr) + def frame_prevl(framelink): # We are evaluating the `frame_pc(framelink)[-1])` with lldb's # REPL, because the lldb API is faulty and it's not possible to cast @@ -673,32 +730,41 @@ def frame_prevl(framelink): # a pointer to it. return framelink - (1 + LJ_FR2 + bc_a(vtou64(dbg_eval('((BCIns *)' + str(frame_pc(framelink)) + ')[-1]')))) + def frame_ispcall(framelink): return (frame_ftsz(framelink) & FRAME['PCALL']) == FRAME['PCALL'] + def frame_sized(framelink): return (frame_ftsz(framelink) & ~FRAME_TYPEP) + def frame_prevd(framelink): return framelink - int(frame_sized(framelink) / sizeof('TValue')) + def frame_type(framelink): return frame_ftsz(framelink) & FRAME_TYPE + def frame_typep(framelink): return frame_ftsz(framelink) & FRAME_TYPEP + def frame_islua(framelink): return frametypes(frame_type(framelink)) == 'L' \ and frame_ftsz(framelink) > 0 + def frame_prev(framelink): return frame_prevl(framelink) if frame_islua(framelink) \ else frame_prevd(framelink) + def frame_sentinel(L): return mref(TValuePtr, L.stack) + LJ_FR2 + # The generator that implements frame iterator. # Every frame is represented as a tuple of framelink and frametop. def frames(L): @@ -712,6 +778,7 @@ def frames(L): break framelink = frame_prev(framelink) + def dump_framelink_slot_address(fr): return '{start:{padding}}:{end:{padding}}'.format( start=hex(int(fr - 1)), @@ -722,6 +789,7 @@ def dump_framelink_slot_address(fr): padding=len(PADDING), ) + def dump_framelink(L, fr): if fr == frame_sentinel(L): return '{addr} [S ] FRAME: dummy L'.format( @@ -737,6 +805,7 @@ def dump_framelink(L, fr): f=dump_lj_tfunc(fr - LJ_FR2), ) + def dump_stack_slot(L, slot, base=None, top=None): base = base or L.base top = top or L.top @@ -750,6 +819,7 @@ def dump_stack_slot(L, slot, base=None, top=None): value=dump_tvalue(slot), ) + def dump_stack(L, base=None, top=None): base = base or L.base top = top or L.top @@ -845,6 +915,7 @@ The command requires no args and dumps current VM and GC states }.items()) ))) + class LJDumpArch(Command): ''' lj-arch @@ -863,6 +934,7 @@ pointers respectively. ) ) + class LJGC(Command): ''' lj-gc @@ -888,6 +960,7 @@ The command requires no args and dumps current GC stats: stats=dump_gc(g) )) + class LJDumpString(Command): ''' lj-str @@ -906,6 +979,7 @@ is replaced with the corresponding error when decoding fails. len=string_ptr.len, )) + class LJDumpTable(Command): ''' lj-tab @@ -950,6 +1024,7 @@ The command receives a GCtab adress and dumps the table contents: n=strx64(mref(NodePtr, node.next)) )) + class LJDumpStack(Command): ''' lj-stack [] @@ -999,6 +1074,7 @@ def register_commands(debugger, commands): ) print('{cmd} command intialized'.format(cmd=cls.command)) + def configure(debugger): global LJ_64, LJ_GC64, LJ_FR2, LJ_DUALNUM, PADDING, LJ_TISNUM, target target = debugger.GetSelectedTarget() -- 2.30.2