From 107905919e3ede0f57017d3c6bf309fa44910ba6 Mon Sep 17 00:00:00 2001 From: Arne Döring Date: Mon, 15 Apr 2019 08:25:21 +0200 Subject: $ command in gdb now works (#10956) --- tools/nim-gdb.py | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/tools/nim-gdb.py b/tools/nim-gdb.py index c1c2e0004..7804ad6e5 100644 --- a/tools/nim-gdb.py +++ b/tools/nim-gdb.py @@ -125,27 +125,36 @@ class NimTypePrinter: class DollarPrintFunction (gdb.Function): "Nim's equivalent of $ operator as a gdb function, available in expressions `print $dollar(myvalue)" - _gdb_dollar_functions = gdb.execute("info functions dollar__", True, True) - dollar_functions = re.findall('NimStringDesc \*(dollar__[A-z0-9_]+?)\(([^,)]*)\);', _gdb_dollar_functions) + dollar_functions = re.findall( + 'NimStringDesc \*(dollar__[A-z0-9_]+?)\(([^,)]*)\);', + gdb.execute("info functions dollar__", True, True) + ) def __init__ (self): super (DollarPrintFunction, self).__init__("dollar") + @staticmethod def invoke_static(arg): - for func, arg_typ in DollarPrintFunction.dollar_functions: + if arg.type.code == gdb.TYPE_CODE_PTR and arg.type.target().name == "NimStringDesc": + return arg - if arg.type.name == arg_typ: + argTypeName = str(arg.type) + + for func, arg_typ in DollarPrintFunction.dollar_functions: + # this way of overload resolution cannot deal with type aliases, + # therefore it won't find all overloads. + if arg_typ == argTypeName: func_value = gdb.lookup_global_symbol(func, gdb.SYMBOL_FUNCTIONS_DOMAIN).value() return func_value(arg) - if arg.type.name + " *" == arg_typ: + elif arg_typ == argTypeName + " *": func_value = gdb.lookup_global_symbol(func, gdb.SYMBOL_FUNCTIONS_DOMAIN).value() return func_value(arg.address) - typeName = arg.type.name - printErrorOnce(typeName, "No suitable Nim $ operator found for type: " + typeName + ".\n") + printErrorOnce(argTypeName, "No suitable Nim $ operator found for type: " + argTypeName + "\n") + return None def invoke(self, arg): return self.invoke_static(arg) @@ -157,14 +166,32 @@ DollarPrintFunction() ################################################################################ class DollarPrintCmd (gdb.Command): - """Dollar print command for Nim, `$ expr` will invoke Nim's $ operator""" + """Dollar print command for Nim, `$ expr` will invoke Nim's $ operator and print the result.""" def __init__ (self): super (DollarPrintCmd, self).__init__ ("$", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION) - def invoke (self, arg, from_tty): + def invoke(self, arg, from_tty): param = gdb.parse_and_eval(arg) - gdb.write(str(DollarPrintFunction.invoke_static(param)) + "\n", gdb.STDOUT) + strValue = DollarPrintFunction.invoke_static(param) + if strValue: + gdb.write( + NimStringPrinter(strValue).to_string() + "\n", + gdb.STDOUT + ) + + # could not find a suitable dollar overload. This here is the + # fallback to get sensible output of basic types anyway. + + elif param.type.code == gdb.TYPE_CODE_ARRAY and param.type.target().name == "char": + gdb.write(param.string("utf-8", "ignore") + "\n", gdb.STDOUT) + elif param.type.code == gdb.TYPE_CODE_INT: + gdb.write(str(int(param)) + "\n", gdb.STDOUT) + elif param.type.name == "NIM_BOOL": + if int(param) != 0: + gdb.write("true\n", gdb.STDOUT) + else: + gdb.write("false\n", gdb.STDOUT) DollarPrintCmd() -- cgit 1.4.1-2-gfad0