diff --git a/tools/gdb/lists.py b/tools/gdb/lists.py index e0999f9f38b..8e6674681f2 100644 --- a/tools/gdb/lists.py +++ b/tools/gdb/lists.py @@ -218,12 +218,12 @@ def dq_check(dq): gdb.write("dq_queue is consistent: {} node(s)\n".format(nb)) -class Nxlistcheck(gdb.Command): +class ListCheck(gdb.Command): """Verify a list consistency""" def __init__(self): - super(Nxlistcheck, self).__init__( - "listcheck", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION + super(ListCheck, self).__init__( + "list_check", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION ) def invoke(self, arg, from_tty): @@ -240,23 +240,22 @@ class Nxlistcheck(gdb.Command): raise gdb.GdbError("Invalid argument type: {}".format(obj.type)) -Nxlistcheck() - - -class Nxlistforentry(gdb.Command): +class ListForEveryEntry(gdb.Command): """Dump list members for a given list""" def __init__(self): - super(Nxlistforentry, self).__init__( - "listforentry", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION + super(ListForEveryEntry, self).__init__( + "list_for_every_entry", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION ) def invoke(self, arg, from_tty): argv = gdb.string_to_argv(arg) if len(argv) != 3: - gdb.write("listforentry takes three arguments" "head, type, member\n") - gdb.write("eg: listforentry &g_list 'struct type' 'node '\n") + gdb.write( + "list_for_every_entry takes three arguments" "head, type, member\n" + ) + gdb.write("eg: list_for_every_entry &g_list 'struct type' 'node '\n") return i = 0 @@ -268,4 +267,5 @@ class Nxlistforentry(gdb.Command): i += 1 -Nxlistforentry() +ListCheck() +ListForEveryEntry() diff --git a/tools/gdb/memdump.py b/tools/gdb/memdump.py index b179ec8a80f..d04da3afe03 100644 --- a/tools/gdb/memdump.py +++ b/tools/gdb/memdump.py @@ -27,13 +27,6 @@ import gdb from lists import sq_for_every, sq_queue_type from utils import get_long_type, get_symbol_value, lookup_type, read_ulong -try: - import numpy as np - from matplotlib import pyplot as plt -except ImportError: - print("Please install matplotlib and numpy to use this command") - print("pip install matplotlib numpy") - MM_ALLOC_BIT = 0x1 MM_PREVFREE_BIT = 0x2 MM_MASK_BIT = MM_ALLOC_BIT | MM_PREVFREE_BIT @@ -784,6 +777,27 @@ have {i} some backtrace leak, total leak memory is {int(leaksize)} bytes\n" class Memmap(gdb.Command): def __init__(self): super(Memmap, self).__init__("memmap", gdb.COMMAND_USER) + self.initialized = False + + def init_once(self) -> bool: + """ + Return True if all prerequisites are met and perform one-time initialization. + """ + if self.initialized: + return True + + try: + import numpy as np + from matplotlib import pyplot as plt + except ImportError: + print("Please install matplotlib and numpy to use this command") + print("pip install matplotlib numpy") + return False + + self.np = np + self.plt = plt + self.initialized = True + return True def save_memory_map(self, mallinfo, output_file): mallinfo = sorted(mallinfo, key=lambda item: item["addr"]) @@ -791,7 +805,7 @@ class Memmap(gdb.Command): size = mallinfo[-1]["addr"] - start order = math.ceil(size**0.5) - img = np.zeros([order, order]) + img = self.np.zeros([order, order]) for node in mallinfo: addr = node["addr"] @@ -800,7 +814,7 @@ class Memmap(gdb.Command): end_index = start_index + size img.flat[start_index:end_index] = 1 + math.log2(node["sequence"] + 1) - plt.imsave(output_file, img, cmap=plt.get_cmap("Greens")) + self.plt.imsave(output_file, img, cmap=self.plt.get_cmap("Greens")) def allocinfo(self): info = [] @@ -831,16 +845,13 @@ class Memmap(gdb.Command): return args.output def invoke(self, args, from_tty): + if not self.init_once(): + return output_file = self.parse_arguments(args.split(" ")) meminfo = self.allocinfo() self.save_memory_map(meminfo, output_file + ".png") -Memdump() -Memleak() -Memmap() - - class Memfrag(gdb.Command): def __init__(self): super(Memfrag, self).__init__("memfrag", gdb.COMMAND_USER) @@ -899,3 +910,6 @@ class Memfrag(gdb.Command): Memfrag() +Memdump() +Memleak() +Memmap() diff --git a/tools/gdb/thread.py b/tools/gdb/thread.py index de596280d58..2791359b8e5 100644 --- a/tools/gdb/thread.py +++ b/tools/gdb/thread.py @@ -1,8 +1,6 @@ ############################################################################ # tools/gdb/thread.py # -# SPDX-License-Identifier: Apache-2.0 -# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. The @@ -20,6 +18,7 @@ # ############################################################################ +import argparse from enum import Enum, auto import gdb @@ -36,7 +35,7 @@ def save_regs(): global saved_regs tcbinfo = gdb.parse_and_eval("g_tcbinfo") - if saved_regs is not None: + if saved_regs: return arch = gdb.selected_frame().architecture() saved_regs = [] @@ -53,7 +52,7 @@ def restore_regs(): tcbinfo = gdb.parse_and_eval("g_tcbinfo") global saved_regs - if saved_regs is None: + if not saved_regs: return arch = gdb.selected_frame().architecture() @@ -68,42 +67,50 @@ def restore_regs(): saved_regs = None -class Nxsetregs(gdb.Command): - """ - Set registers to the specified values. - Usage: nxsetregs [regs] +class SetRegs(gdb.Command): + """Set registers to the specified values. + Usage: setregs [regs] - Etc: nxsetregs - nxsetregs g_current_regs[0] - nxsetregs tcb->xcp.regs - Nxsetregs g_pidhash[0].tcb->xcp.regs - - Default regs is g_current_regs[0],if regs is NULL, it will not set registers. + Etc: setregs + setregs tcb->xcp.regs + setregs g_pidhash[0]->xcp.regs + Default regs is tcbinfo_current_regs(),if regs is NULL, it will not set registers. """ def __init__(self): - super(Nxsetregs, self).__init__("nxsetregs", gdb.COMMAND_USER) + super(SetRegs, self).__init__("setregs", gdb.COMMAND_USER) - def invoke(self, args, from_tty): - gdb.execute("set $_current_regs=tcbinfo_running_regs()") - current_regs = gdb.parse_and_eval("$_current_regs") - tcbinfo = gdb.parse_and_eval("g_tcbinfo") - arg = args.split(" ") + def invoke(self, arg, from_tty): + parser = argparse.ArgumentParser( + description="Set registers to the specified values" + ) - if arg[0] != "": - regs = gdb.parse_and_eval(f"{arg[0]}").cast( + parser.add_argument( + "regs", + nargs="?", + default="", + help="The registers to set, use tcbinfo_current_regs() if not specified", + ) + + try: + args = parser.parse_args(gdb.string_to_argv(arg)) + except SystemExit: + return + + if args and args.regs: + regs = gdb.parse_and_eval(f"{args.regs}").cast( utils.lookup_type("char").pointer() ) else: - gdb.execute("set $_current_regs=tcbinfo_current_regs()") - current_regs = gdb.parse_and_eval("$_current_regs") + current_regs = gdb.parse_and_eval("tcbinfo_current_regs()") regs = current_regs.cast(utils.lookup_type("char").pointer()) if regs == 0: gdb.write("regs is NULL\n") return + tcbinfo = gdb.parse_and_eval("g_tcbinfo") save_regs() arch = gdb.selected_frame().architecture() i = 0 @@ -122,6 +129,8 @@ class Nxsetregs(gdb.Command): class Nxinfothreads(gdb.Command): + """Display information of all threads""" + def __init__(self): super(Nxinfothreads, self).__init__("info threads", gdb.COMMAND_USER) @@ -211,6 +220,8 @@ class Nxinfothreads(gdb.Command): class Nxthread(gdb.Command): + """Switch to a specified thread""" + def __init__(self): super(Nxthread, self).__init__("thread", gdb.COMMAND_USER) @@ -237,7 +248,7 @@ class Nxthread(gdb.Command): except gdb.error and UnicodeDecodeError: gdb.write(f"Thread {i}\n") - gdb.execute(f"nxsetregs g_pidhash[{i}]->xcp.regs") + gdb.execute(f"setregs g_pidhash[{i}]->xcp.regs") cmd_arg = "" for cmd in arg[2:]: cmd_arg += cmd + " " @@ -269,7 +280,7 @@ class Nxthread(gdb.Command): except gdb.error and UnicodeDecodeError: gdb.write(f"Thread {i}\n") - gdb.execute(f"nxsetregs g_pidhash[{i}]->xcp.regs") + gdb.execute(f"setregs g_pidhash[{i}]->xcp.regs") gdb.execute(f"{cmd}\n") restore_regs() @@ -280,12 +291,14 @@ class Nxthread(gdb.Command): ): restore_regs() else: - gdb.execute("nxsetregs g_pidhash[%s]->xcp.regs" % arg[0]) + gdb.execute("setregs g_pidhash[%s]->xcp.regs" % arg[0]) else: gdb.write(f"Invalid thread id {arg[0]}\n") class Nxcontinue(gdb.Command): + """Restore the registers and continue the execution""" + def __init__(self): super(Nxcontinue, self).__init__("nxcontinue", gdb.COMMAND_USER) @@ -295,6 +308,8 @@ class Nxcontinue(gdb.Command): class Nxstep(gdb.Command): + """Restore the registers and step the execution""" + def __init__(self): super(Nxstep, self).__init__("nxstep", gdb.COMMAND_USER) @@ -500,7 +515,7 @@ class Ps(gdb.Command): def register_commands(): - Nxsetregs() + SetRegs() Ps() # Disable thread commands for core dump and gdb-stub. @@ -508,7 +523,7 @@ def register_commands(): ncpus = utils.get_symbol_value("CONFIG_SMP_NCPUS") or 1 nthreads = len(gdb.selected_inferior().threads()) if nthreads <= ncpus: - Nxsetregs() + SetRegs() Nxinfothreads() Nxthread() Nxcontinue()