$ command in gdb now works (#10956)

This commit is contained in:
Arne Döring 2019-04-15 08:25:21 +02:00 • committed by Andreas Rumpf
commit 107905919e

View file

@ -125,27 +125,36 @@ class NimTypePrinter:
class DollarPrintFunction (gdb.Function): class DollarPrintFunction (gdb.Function):
"Nim's equivalent of $ operator as a gdb function, available in expressions `print $dollar(myvalue)" "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(
dollar_functions = re.findall('NimStringDesc \*(dollar__[A-z0-9_]+?)\(([^,)]*)\);', _gdb_dollar_functions) 'NimStringDesc \*(dollar__[A-z0-9_]+?)\(([^,)]*)\);',
gdb.execute("info functions dollar__", True, True)
)
def __init__ (self): def __init__ (self):
super (DollarPrintFunction, self).__init__("dollar") super (DollarPrintFunction, self).__init__("dollar")
@staticmethod @staticmethod
def invoke_static(arg): 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() func_value = gdb.lookup_global_symbol(func, gdb.SYMBOL_FUNCTIONS_DOMAIN).value()
return func_value(arg) 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() func_value = gdb.lookup_global_symbol(func, gdb.SYMBOL_FUNCTIONS_DOMAIN).value()
return func_value(arg.address) return func_value(arg.address)
typeName = arg.type.name printErrorOnce(argTypeName, "No suitable Nim $ operator found for type: " + argTypeName + "\n")
printErrorOnce(typeName, "No suitable Nim $ operator found for type: " + typeName + ".\n") return None
def invoke(self, arg): def invoke(self, arg):
return self.invoke_static(arg) return self.invoke_static(arg)
@ -157,14 +166,32 @@ DollarPrintFunction()
################################################################################ ################################################################################
class DollarPrintCmd (gdb.Command): 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): def __init__ (self):
super (DollarPrintCmd, self).__init__ ("$", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION) 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) 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() DollarPrintCmd()