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