From 58e4ec577f3168eba282e9ad36257e9bee0702f2 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Wed, 15 Oct 2014 16:41:14 -0700 Subject: Always print symbols if known for pointers --- src/compat/option.py | 2 +- src/main-gdb-head.py | 79 +++++++++++++++++++++++++++++++++++++++++--- src/map/magic-expr.py | 2 +- src/map/magic-interpreter.py | 4 +-- src/map/magic-stmt.py | 2 +- src/map/script-persist.py | 18 +++++++--- src/strings/xstring.py | 12 +++---- src/strings/zstring.py | 12 +++---- tools/debug-debug.gdb | 2 +- 9 files changed, 105 insertions(+), 28 deletions(-) diff --git a/src/compat/option.py b/src/compat/option.py index a410ac8..60a98d9 100644 --- a/src/compat/option.py +++ b/src/compat/option.py @@ -33,5 +33,5 @@ class Option(object): ('tmwa::None()', 'None'), ('tmwa::Some(1)', 'Some(1)'), ('tmwa::Option>(tmwa::None)', 'None>'), - ('tmwa::Some(tmwa::borrow(option_borrow_thingy))', 'regex:Some>\(0x[0-9a-f]* \)'), + ('tmwa::Some(tmwa::borrow(option_borrow_thingy))', 'Some>()'), ] diff --git a/src/main-gdb-head.py b/src/main-gdb-head.py index 2dac471..6ae204b 100644 --- a/src/main-gdb-head.py +++ b/src/main-gdb-head.py @@ -29,22 +29,55 @@ def get_basic_type(type_): type_ = type_.strip_typedefs() return type_.unqualified() +def info_symbol(addr): + ''' returns (symbol, offset, section, lib or None) or None? + ''' + info = gdb.execute('info symbol %d' % addr, to_string=True) + try: + sym_and_off, sec_and_lib = info.split(' in section ') + except ValueError: + return None + try: + sym, off = sym_and_off.split(' + ') + except ValueError: + sym = sym_and_off + off = 0 + else: + off = int(off, 10) + try: + sec, lib = sec_and_lib.split(' of ') + except ValueError: + sec = sec_and_lib + lib = None + return (sym, off, sec, lib) + def finish(): - global finish, initial_globals, FastPrinters, EnumPrinter + global finish, initial_globals, FastPrinters, EnumPrinter, PointerPrinter final_globals = {id(v):v for v in globals().values()} diff = set(final_globals.keys()) - set(initial_globals.keys()) \ - - {'finish', 'initial_globals', 'FastPrinters'} + - { + 'finish', + 'initial_globals', + 'FastPrinters', + 'EnumPrinter', + 'PointerPrinter', + } fp = FastPrinters() ep = EnumPrinter + ptrp = PointerPrinter # After this, don't access any more globals in this function. - del finish, initial_globals, FastPrinters, EnumPrinter + del finish, initial_globals, FastPrinters, EnumPrinter, PointerPrinter for i in diff: v = final_globals[i] if hasattr(v, 'children') or hasattr(v, 'to_string'): fp.add_printer(v) + # TODO see if there's a way to detect the top-level printers too + # the problem is that some of them collide and the order *is* + # important, but sets and dicts don't preserve order. + # Particularly, 'PointerPrinter' must come after 'FastPrinters'. obj = gdb.current_objfile() if obj is None: @@ -53,9 +86,12 @@ def finish(): else: filename = obj.filename obj.pretty_printers.append(fp) + n = len(obj.pretty_printers) obj.pretty_printers.append(ep) - print('Added %d+1 custom printers for %s' - % (len(fp.printers), filename)) + obj.pretty_printers.append(ptrp) + n = len(obj.pretty_printers) - n + print('Added %d+%d custom printers for %s' + % (len(fp.printers), n, filename)) class EnumPrinter(object): __slots__ = ('_value') @@ -82,6 +118,39 @@ class EnumPrinter(object): scope = get_basic_type(v.type).tag return '%s::%s' % (scope, name) +class PointerPrinter(object): + __slots__ = ('_value') + name = 'any-symbol-pointer' + enabled = True + + def __new__(cls, v): + type = get_basic_type(v.type) + if type.code != gdb.TYPE_CODE_PTR: + return None + return object.__new__(cls) + + def __init__(self, v): + self._value = v + + def to_string(self): + v = self._value + addr = int(v.cast(gdb.lookup_type('uintptr_t'))) + if not addr: + s = 'nullptr' + else: + try: + sym, off, sec, lib = info_symbol(addr) + except: + s = '' % addr + else: + if off: + s = '<%s+%d>' % off + else: + s = '<%s>' % sym + # TODO should I add (type *) ? + return s + + class FastPrinters(object): ''' printer dispatch the way gdb *should* have done it ''' diff --git a/src/map/magic-expr.py b/src/map/magic-expr.py index 0d9db55..c48b79b 100644 --- a/src/map/magic-expr.py +++ b/src/map/magic-expr.py @@ -34,5 +34,5 @@ class fun_t(object): ('static_cast(nullptr)', '(fun_t *) nullptr'), ('new tmwa::magic::fun_t{"name"_s, "sig"_s, \'\\0\', nullptr}', - 'regex:\(fun_t \*\) = \{->name = "name", ->signature = "sig", ->ret_ty = 0 \'\\\\000\', ->fun = (0x)?0}'), + '(fun_t *) = {->name = "name", ->signature = "sig", ->ret_ty = 0 \'\\000\', ->fun = nullptr}'), ] diff --git a/src/map/magic-interpreter.py b/src/map/magic-interpreter.py index bbf135c..141cd22 100644 --- a/src/map/magic-interpreter.py +++ b/src/map/magic-interpreter.py @@ -177,7 +177,7 @@ class effect_t(object): ('tmwa::magic::effect_t(tmwa::magic::EffectEnd{}, tmwa::dumb_ptr())', '{> = {(tmwa::magic::EffectEnd) = {}}, next = 0x0}'), ('tmwa::magic::effect_t(tmwa::magic::EffectCall{nullptr, tmwa::dumb_ptr>>(), tmwa::dumb_ptr()}, tmwa::dumb_ptr())', - '{> = {(tmwa::magic::EffectCall) = {formalv = 0x0, actualvp = 0x0, body = 0x0}}, next = 0x0}'), + '{> = {(tmwa::magic::EffectCall) = {formalv = nullptr, actualvp = 0x0, body = 0x0}}, next = 0x0}'), ] @@ -211,5 +211,5 @@ class cont_activation_record_t(object): ('tmwa::magic::cont_activation_record_t(tmwa::magic::CarFor{42, tmwa::dumb_ptr(), 123, 456}, tmwa::dumb_ptr())', '{> = {(tmwa::magic::CarFor) = {id = 42, body = 0x0, current = 123, stop = 456}}, return_location = 0x0}'), ('tmwa::magic::cont_activation_record_t(tmwa::magic::CarProc{123, nullptr, tmwa::dumb_ptr()}, tmwa::dumb_ptr())', - '{> = {(tmwa::magic::CarProc) = {args_nr = 123, formalap = 0x0, old_actualpa = 0x0 = {sz = 0}}}, return_location = 0x0}'), + '{> = {(tmwa::magic::CarProc) = {args_nr = 123, formalap = nullptr, old_actualpa = 0x0 = {sz = 0}}}, return_location = 0x0}'), ] diff --git a/src/map/magic-stmt.py b/src/map/magic-stmt.py index 14289ef..65f44a7 100644 --- a/src/map/magic-stmt.py +++ b/src/map/magic-stmt.py @@ -33,5 +33,5 @@ class op_t(object): ('static_cast(nullptr)', '(op_t *) nullptr'), ('new tmwa::magic::op_t{"name"_s, "sig"_s, nullptr}', - 'regex:\(op_t \*\) = \{->name = "name", ->signature = "sig", ->op = (0x)?0}'), + '(op_t *) = {->name = "name", ->signature = "sig", ->op = nullptr}'), ] diff --git a/src/map/script-persist.py b/src/map/script-persist.py index 454c828..df60cf4 100644 --- a/src/map/script-persist.py +++ b/src/map/script-persist.py @@ -3,7 +3,17 @@ class script_data(object): test_extra = ''' using tmwa::operator "" _s; - #include "../map/script-parse.hpp" + + #include "../map/script-parse-internal.hpp" + + static + tmwa::Borrowed fake_script() + { + static + const std::vector buffer; + return borrow(reinterpret_cast(buffer)); + } + ''' tests = [ @@ -19,10 +29,8 @@ class script_data(object): '{> = {(tmwa::ScriptDataArg) = {numi = 0}}, }'), ('tmwa::script_data(tmwa::ScriptDataVariable{tmwa::SIR()})', '{> = {(tmwa::ScriptDataVariable) = {reg = {impl = 0}}}, }'), - # the {script = } is almost certainly a bug in gdb's 'set print address' - # but the most I can do is check for changes. - ('tmwa::script_data(tmwa::ScriptDataRetInfo{tmwa::borrow(*tmwa::parse_script("{}"_s, 1, true).release())})', - 'regex:\{> = \{\(tmwa::ScriptDataRetInfo\) = \{script = \}\}, \}'), + ('tmwa::script_data(tmwa::ScriptDataRetInfo{fake_script()})', + '{> = {(tmwa::ScriptDataRetInfo) = {script = }}, }'), ('tmwa::script_data(tmwa::ScriptDataFuncRef{404})', '{> = {(tmwa::ScriptDataFuncRef) = {numi = 404}}, }'), ] diff --git a/src/strings/xstring.py b/src/strings/xstring.py index b2e33bb..ae764df 100644 --- a/src/strings/xstring.py +++ b/src/strings/xstring.py @@ -22,10 +22,10 @@ class XString(object): ''' tests = [ - ('tmwa::XString(""_s)', '"" = {base = 0x0}'), - ('tmwa::XString("Hello"_s)', '"Hello" = {base = 0x0}'), - ('tmwa::XString("' + str256[:-2] + '"_s)', '"' + str256[:-2] + '" = {base = 0x0}'), - ('tmwa::XString("' + str256[:-1] + '"_s)', '"' + str256[:-1] + '" = {base = 0x0}'), - ('tmwa::XString("' + str256 + '"_s)', '"' + str256 + '" = {base = 0x0}'), - ('tmwa::XString("' + str256 + 'x"_s)', '"' + str256 + 'x" = {base = 0x0}'), + ('tmwa::XString(""_s)', '"" = {base = nullptr}'), + ('tmwa::XString("Hello"_s)', '"Hello" = {base = nullptr}'), + ('tmwa::XString("' + str256[:-2] + '"_s)', '"' + str256[:-2] + '" = {base = nullptr}'), + ('tmwa::XString("' + str256[:-1] + '"_s)', '"' + str256[:-1] + '" = {base = nullptr}'), + ('tmwa::XString("' + str256 + '"_s)', '"' + str256 + '" = {base = nullptr}'), + ('tmwa::XString("' + str256 + 'x"_s)', '"' + str256 + 'x" = {base = nullptr}'), ] diff --git a/src/strings/zstring.py b/src/strings/zstring.py index f57252f..570c8f1 100644 --- a/src/strings/zstring.py +++ b/src/strings/zstring.py @@ -22,10 +22,10 @@ class ZString(object): ''' tests = [ - ('tmwa::ZString(""_s)', '"" = {base = 0x0}'), - ('tmwa::ZString("Hello"_s)', '"Hello" = {base = 0x0}'), - ('tmwa::ZString("' + str256[:-2] + '"_s)', '"' + str256[:-2] + '" = {base = 0x0}'), - ('tmwa::ZString("' + str256[:-1] + '"_s)', '"' + str256[:-1] + '" = {base = 0x0}'), - ('tmwa::ZString("' + str256 + '"_s)', '"' + str256 + '" = {base = 0x0}'), - ('tmwa::ZString("' + str256 + 'x"_s)', '"' + str256 + 'x" = {base = 0x0}'), + ('tmwa::ZString(""_s)', '"" = {base = nullptr}'), + ('tmwa::ZString("Hello"_s)', '"Hello" = {base = nullptr}'), + ('tmwa::ZString("' + str256[:-2] + '"_s)', '"' + str256[:-2] + '" = {base = nullptr}'), + ('tmwa::ZString("' + str256[:-1] + '"_s)', '"' + str256[:-1] + '" = {base = nullptr}'), + ('tmwa::ZString("' + str256 + '"_s)', '"' + str256 + '" = {base = nullptr}'), + ('tmwa::ZString("' + str256 + 'x"_s)', '"' + str256 + 'x" = {base = nullptr}'), ] diff --git a/tools/debug-debug.gdb b/tools/debug-debug.gdb index e1fa19e..314e049 100644 --- a/tools/debug-debug.gdb +++ b/tools/debug-debug.gdb @@ -19,7 +19,7 @@ def hit_breakpoint(): sys.stdout.write('.') value = str(gdb.parse_and_eval('*&value')) expected = gdb.parse_and_eval('expected').string() - if expected.startswith('regex:'): + if False and expected.startswith('regex:'): def compare(value, expected): m = re.match(expected[6:], value) return m and m.end() == m.endpos -- cgit v1.2.3-70-g09d2