From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (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 7690D469719 for ; Thu, 13 Feb 2020 14:48:41 +0300 (MSK) Date: Thu, 13 Feb 2020 14:48:37 +0300 From: Igor Munkin Message-ID: <20200213114837.GP26983@tarantool.org> References: <3bfab5cce3e3816bc1c8c969e33204c2a00c929a.1580917791.git.imun@tarantool.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <3bfab5cce3e3816bc1c8c969e33204c2a00c929a.1580917791.git.imun@tarantool.org> Subject: Re: [Tarantool-patches] [PATCH v2 luajit 3/3] gdb: enhance the extension loading List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Damn the old Python: | (gdb) source ~/luajit-gdb.py | Traceback (most recent call last): | File "~/luajit-gdb.py", line 686, in | File "~/luajit-gdb.py", line 675, in load | File "~/luajit-gdb.py", line 468, in __init__ | NameError: global name '__class__' is not defined | (gdb) python | >import sys | >print(sys.version) | >2.7.5 (default, Aug 7 2019, 00:51:29) | [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] I'll fix the issue and send either diff or a new patch for this one in a jiffy. On 05.02.20, Igor Munkin wrote: > Definition of LJ_64, LJ_GC64 and LJ_FR2 constants in script requires > LuaJIT internal enum values to be presented in the executable. Otherwise > the extension loading fails. The changes handles exception for the > following scenarios: > * luajit-gdb.py is loaded for an arbitrary executable, e.g. /bin/echo > * luajit-gdb.py is loaded for a luajit executable (or the one linked > against libluajit) but debug info is not found > > Signed-off-by: Igor Munkin > --- > src/luajit-gdb.py | 102 ++++++++++++++++++++-------------------------- > 1 file changed, 45 insertions(+), 57 deletions(-) > > diff --git a/src/luajit-gdb.py b/src/luajit-gdb.py > index 90df101..bc37674 100644 > --- a/src/luajit-gdb.py > +++ b/src/luajit-gdb.py > @@ -1,3 +1,6 @@ > +# GDB extension for LuaJIT post-mortem analysis. > +# To use, just put 'source /src/luajit-gdb.py' in gdb. > + > import re > import gdb > import sys > @@ -151,11 +154,9 @@ def frame_prev(framelink): > > # Const {{{ > > -LJ_64 = str(gdb.parse_and_eval('IRT_PTR')) == 'IRT_P64' > - > -LJ_GC64 = str(gdb.parse_and_eval('IRT_PGC')) == 'IRT_P64' > - > -LJ_FR2 = LJ_GC64 > +LJ_64 = None > +LJ_GC64 = None > +LJ_FR2 = None > > LJ_GCVMASK = ((1 << 47) - 1) > > @@ -460,7 +461,14 @@ def dump_gc(g): > > return '\n'.join(map(lambda s: '\t' + s, stats)) > > -class LJDumpArch(gdb.Command): > + > +class LJBase(gdb.Command): > + > + def __init__(self, name): > + super(__class__, self).__init__(name, gdb.COMMAND_DATA) > + gdb.write('{} command initialized\n'.format(name)) > + > +class LJDumpArch(LJBase): > ''' > lj-arch > > @@ -469,20 +477,13 @@ compile-time flags. These values define the sizes of host and GC > pointers respectively. > ''' > > - def __init__(self): > - super(LJDumpArch, self).__init__( > - 'lj-arch', gdb.COMMAND_DATA > - ) > - > def invoke(self, arg, from_tty): > gdb.write('LJ_64: {LJ_64}, LJ_GC64: {LJ_GC64}\n'.format( > LJ_64 = LJ_64, > LJ_GC64 = LJ_GC64 > )) > > -LJDumpArch() > - > -class LJDumpTValue(gdb.Command): > +class LJDumpTValue(LJBase): > ''' > lj-tv > > @@ -511,18 +512,11 @@ Whether the type of the given address differs from the listed above, then > error message occurs. > ''' > > - def __init__(self): > - super(LJDumpTValue, self).__init__( > - 'lj-tv', gdb.COMMAND_DATA > - ) > - > def invoke(self, arg, from_tty): > tv = cast('TValue *', parse_arg(arg)) > gdb.write('{}\n'.format(dump_tvalue(tv))) > > -LJDumpTValue() > - > -class LJDumpString(gdb.Command): > +class LJDumpString(LJBase): > ''' > lj-str > > @@ -533,11 +527,6 @@ the payload, size in bytes and hash. > is replaced with the corresponding error when decoding fails. > ''' > > - def __init__(self): > - super(LJDumpString, self).__init__( > - 'lj-str', gdb.COMMAND_DATA > - ) > - > def invoke(self, arg, from_tty): > string = cast('GCstr *', parse_arg(arg)) > gdb.write("String: {body} [{len} bytes] with hash {hash}\n".format( > @@ -546,10 +535,7 @@ is replaced with the corresponding error when decoding fails. > len = string['len'], > )) > > - > -LJDumpString() > - > -class LJDumpTable(gdb.Command): > +class LJDumpTable(LJBase): > ''' > lj-tab > > @@ -561,10 +547,6 @@ The command recieves a GCtab adress and dumps the table contents: > : { } => { }; next = > ''' > > - def __init__(self): > - super(LJDumpTable, self).__init__( > - 'lj-tab', gdb.COMMAND_DATA) > - > def invoke(self, arg, from_tty): > t = cast('GCtab *', parse_arg(arg)) > array = mref('TValue *', t['array']) > @@ -598,9 +580,7 @@ The command recieves a GCtab adress and dumps the table contents: > n = mref('struct Node *', node['next']) > )) > > -LJDumpTable() > - > -class LJDumpStack(gdb.Command): > +class LJDumpStack(LJBase): > ''' > lj-stack [] > > @@ -633,16 +613,10 @@ coroutine guest stack: > If L is ommited the main coroutine is used. > ''' > > - def __init__(self): > - super(LJDumpStack, self).__init__( > - 'lj-stack', gdb.COMMAND_DATA) > - > def invoke(self, arg, from_tty): > gdb.write('{}\n'.format(dump_stack(L(parse_arg(arg))))) > > -LJDumpStack() > - > -class LJState(gdb.Command): > +class LJState(LJBase): > ''' > lj-state > The command requires no args and dumps current VM and GC states > @@ -651,10 +625,6 @@ The command requires no args and dumps current VM and GC states > * JIT state: > ''' > > - def __init__(self): > - super(LJState, self).__init__( > - 'lj-state', gdb.COMMAND_DATA) > - > def invoke(self, arg, from_tty): > g = G(L(None)) > gdb.write('{}\n'.format('\n'.join( > @@ -665,9 +635,7 @@ The command requires no args and dumps current VM and GC states > }.items()) > ))) > > -LJState() > - > -class LJGC(gdb.Command): > +class LJGC(LJBase): > ''' > lj-gc > > @@ -685,10 +653,6 @@ The command requires no args and dumps current GC stats: > * weak: > ''' > > - def __init__(self): > - super(LJGC, self).__init__( > - 'lj-gc', gdb.COMMAND_DATA) > - > def invoke(self, arg, from_tty): > g = G(L(None)) > gdb.write('GC stats: {state}\n{stats}\n'.format( > @@ -696,4 +660,28 @@ The command requires no args and dumps current GC stats: > stats = dump_gc(g) > )) > > -LJGC() > +def load(commands): > + global LJ_64, LJ_GC64, LJ_FR2 > + > + try: > + LJ_64 = str(gdb.parse_and_eval('IRT_PTR')) == 'IRT_P64' > + LJ_FR2 = LJ_GC64 = str(gdb.parse_and_eval('IRT_PGC')) == 'IRT_P64' > + except: > + gdb.write('luajit-gdb.py failed to load: ' > + 'no debugging symbols found for libluajit\n') > + return > + > + for name, command in commands.items(): > + command(name) > + > + gdb.write('luajit-gdb.py is successfully loaded\n') > + > +load({ > + 'lj-arch': LJDumpArch, > + 'lj-tv': LJDumpTValue, > + 'lj-str': LJDumpString, > + 'lj-tab': LJDumpTable, > + 'lj-stack': LJDumpStack, > + 'lj-state': LJState, > + 'lj-gc': LJGC, > +}) > -- > 2.24.0 > -- Best regards, IM