From a633a4b8001a7f2a12584f267a3280990d9ababa Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:48:57 +0800 Subject: scripts/gdb: fix timerlist parsing issue Patch series "Fix some GDB command error and add some GDB commands", v3. Fix some GDB command errors and add some useful GDB commands. This patch (of 5): Commit 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") and commit 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") move 'tick_stopped' and 'nohz_mode' to flags field which will break the gdb lx-mounts command: (gdb) lx-timerlist Python Exception : There is no member named nohz_mode. Error occurred in Python: There is no member named nohz_mode. (gdb) lx-timerlist Python Exception : There is no member named tick_stopped. Error occurred in Python: There is no member named tick_stopped. We move 'tick_stopped' and 'nohz_mode' to flags field instead. Link: https://lkml.kernel.org/r/20240723064902.124154-1-kuan-ying.lee@canonical.com Link: https://lkml.kernel.org/r/20240723064902.124154-2-kuan-ying.lee@canonical.com Fixes: a478ffb2ae23 ("tick: Move individual bit features to debuggable mask accesses") Fixes: 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/timerlist.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'scripts/gdb/linux') diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py index 64bc87191003..98445671fe83 100644 --- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -87,21 +87,22 @@ def print_cpu(hrtimer_bases, cpu, max_clock_bases): text += "\n" if constants.LX_CONFIG_TICK_ONESHOT: - fmts = [(" .{} : {}", 'nohz_mode'), - (" .{} : {} nsecs", 'last_tick'), - (" .{} : {}", 'tick_stopped'), - (" .{} : {}", 'idle_jiffies'), - (" .{} : {}", 'idle_calls'), - (" .{} : {}", 'idle_sleeps'), - (" .{} : {} nsecs", 'idle_entrytime'), - (" .{} : {} nsecs", 'idle_waketime'), - (" .{} : {} nsecs", 'idle_exittime'), - (" .{} : {} nsecs", 'idle_sleeptime'), - (" .{}: {} nsecs", 'iowait_sleeptime'), - (" .{} : {}", 'last_jiffies'), - (" .{} : {}", 'next_timer'), - (" .{} : {} nsecs", 'idle_expires')] - text += "\n".join([s.format(f, ts[f]) for s, f in fmts]) + TS_FLAG_STOPPED = 1 << 1 + TS_FLAG_NOHZ = 1 << 4 + text += f" .{'nohz':15s}: {int(bool(ts['flags'] & TS_FLAG_NOHZ))}\n" + text += f" .{'last_tick':15s}: {ts['last_tick']}\n" + text += f" .{'tick_stopped':15s}: {int(bool(ts['flags'] & TS_FLAG_STOPPED))}\n" + text += f" .{'idle_jiffies':15s}: {ts['idle_jiffies']}\n" + text += f" .{'idle_calls':15s}: {ts['idle_calls']}\n" + text += f" .{'idle_sleeps':15s}: {ts['idle_sleeps']}\n" + text += f" .{'idle_entrytime':15s}: {ts['idle_entrytime']} nsecs\n" + text += f" .{'idle_waketime':15s}: {ts['idle_waketime']} nsecs\n" + text += f" .{'idle_exittime':15s}: {ts['idle_exittime']} nsecs\n" + text += f" .{'idle_sleeptime':15s}: {ts['idle_sleeptime']} nsecs\n" + text += f" .{'iowait_sleeptime':15s}: {ts['iowait_sleeptime']} nsecs\n" + text += f" .{'last_jiffies':15s}: {ts['last_jiffies']}\n" + text += f" .{'next_timer':15s}: {ts['next_timer']}\n" + text += f" .{'idle_expires':15s}: {ts['idle_expires']} nsecs\n" text += "\njiffies: {}\n".format(jiffies) text += "\n" -- cgit v1.2.3 From 0c77e103c45fa1b119f5d3bb4625eee081c1a6cf Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:48:58 +0800 Subject: scripts/gdb: add iteration function for rbtree Add inorder iteration function for rbtree usage. This is a preparation patch for the next patch to fix the gdb mounts issue. Link: https://lkml.kernel.org/r/20240723064902.124154-3-kuan-ying.lee@canonical.com Fixes: 2eea9ce4310d ("mounts: keep list of mounts in an rbtree") Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/rbtree.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts/gdb/linux') diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py index fe462855eefd..fcbcc5f4153c 100644 --- a/scripts/gdb/linux/rbtree.py +++ b/scripts/gdb/linux/rbtree.py @@ -9,6 +9,18 @@ from linux import utils rb_root_type = utils.CachedType("struct rb_root") rb_node_type = utils.CachedType("struct rb_node") +def rb_inorder_for_each(root): + def inorder(node): + if node: + yield from inorder(node['rb_left']) + yield node + yield from inorder(node['rb_right']) + + yield from inorder(root['rb_node']) + +def rb_inorder_for_each_entry(root, gdbtype, member): + for node in rb_inorder_for_each(root): + yield utils.container_of(node, gdbtype, member) def rb_first(root): if root.type == rb_root_type.get_type(): -- cgit v1.2.3 From 4b183f613924ad536be2f8bd12b307e9c5a96bf6 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:48:59 +0800 Subject: scripts/gdb: fix lx-mounts command error (gdb) lx-mounts mount super_block devname pathname fstype options Python Exception : There is no member named list. Error occurred in Python: There is no member named list. We encounter the above issue after commit 2eea9ce4310d ("mounts: keep list of mounts in an rbtree"). The commit move a mount from list into rbtree. So we can instead use rbtree to iterate all mounts information. Link: https://lkml.kernel.org/r/20240723064902.124154-4-kuan-ying.lee@canonical.com Fixes: 2eea9ce4310d ("mounts: keep list of mounts in an rbtree") Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/proc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts/gdb/linux') diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 43c687e7a69d..65dd1bd12964 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -18,6 +18,7 @@ from linux import utils from linux import tasks from linux import lists from linux import vfs +from linux import rbtree from struct import * @@ -172,8 +173,7 @@ values of that process namespace""" gdb.write("{:^18} {:^15} {:>9} {} {} options\n".format( "mount", "super_block", "devname", "pathname", "fstype")) - for mnt in lists.list_for_each_entry(namespace['list'], - mount_ptr_type, "mnt_list"): + for mnt in rbtree.rb_inorder_for_each_entry(namespace['mounts'], mount_ptr_type, "mnt_node"): devname = mnt['mnt_devname'].string() devname = devname if devname else "none" -- cgit v1.2.3 From 35249f68b5d38bff1c616cc9761ecc3d820163b1 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:49:00 +0800 Subject: scripts/gdb: add 'lx-stack_depot_lookup' command. This command allows users to quickly retrieve a stacktrace using a handle obtained from a memory coredump. Example output: (gdb) lx-stack_depot_lookup 0x00c80300 0xffff8000807965b4 : mov x20, x0 0xffff800081a077d8 : mov x1, x0 0xffff800081a079a0 : cbnz w0, 0xffff800081a07968 0xffff800082f4a3fc : ldr x19, [sp, #16] 0xffff800080a0fb34 : ldp x3, x4, [sp, #96] 0xffff800080a0a550 : ldp x19, x20, [sp, #16] 0xffff8000808e7b40 : mov w5, w0 0xffff800080a0b8ac : mov x23, x0 0xffff800080914a48 : mov x6, x0 0xffff8000809151c4 : ldr x21, [sp, #32] Link: https://lkml.kernel.org/r/20240723064902.124154-5-kuan-ying.lee@canonical.com Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/stackdepot.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'scripts/gdb/linux') diff --git a/scripts/gdb/linux/stackdepot.py b/scripts/gdb/linux/stackdepot.py index bb3a0f843931..37313a5a51a0 100644 --- a/scripts/gdb/linux/stackdepot.py +++ b/scripts/gdb/linux/stackdepot.py @@ -13,6 +13,13 @@ if constants.LX_CONFIG_STACKDEPOT: stack_record_type = utils.CachedType('struct stack_record') DEPOT_STACK_ALIGN = 4 +def help(): + t = """Usage: lx-stack_depot_lookup [Hex handle value] + Example: + lx-stack_depot_lookup 0x00c80300\n""" + gdb.write("Unrecognized command\n") + raise gdb.GdbError(t) + def stack_depot_fetch(handle): global DEPOT_STACK_ALIGN global stack_record_type @@ -57,3 +64,23 @@ def stack_depot_print(handle): gdb.execute("x /i 0x%x" % (int(entries[i]))) except Exception as e: gdb.write("%s\n" % e) + +class StackDepotLookup(gdb.Command): + """Search backtrace by handle""" + + def __init__(self): + if constants.LX_CONFIG_STACKDEPOT: + super(StackDepotLookup, self).__init__("lx-stack_depot_lookup", gdb.COMMAND_SUPPORT) + + def invoke(self, args, from_tty): + if not constants.LX_CONFIG_STACKDEPOT: + raise gdb.GdbError('CONFIG_STACKDEPOT is not set') + + argv = gdb.string_to_argv(args) + if len(argv) == 1: + handle = int(argv[0], 16) + stack_depot_print(gdb.Value(handle).cast(utils.get_uint_type())) + else: + help() + +StackDepotLookup() -- cgit v1.2.3 From 0833952c0768daea7d9b6dc59a35bef309234b88 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:49:01 +0800 Subject: scripts/gdb: add 'lx-kasan_mem_to_shadow' command This command allows users to quickly translate memory address to the kasan shadow memory address. Example output: (gdb) lx-kasan_mem_to_shadow 0xffff000019acc008 shadow addr: 0xffff600003359801 Link: https://lkml.kernel.org/r/20240723064902.124154-6-kuan-ying.lee@canonical.com Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/kasan.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ scripts/gdb/vmlinux-gdb.py | 1 + 2 files changed, 45 insertions(+) create mode 100644 scripts/gdb/linux/kasan.py (limited to 'scripts/gdb/linux') diff --git a/scripts/gdb/linux/kasan.py b/scripts/gdb/linux/kasan.py new file mode 100644 index 000000000000..56730b3fde0b --- /dev/null +++ b/scripts/gdb/linux/kasan.py @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2024 Canonical Ltd. +# +# Authors: +# Kuan-Ying Lee +# + +import gdb +from linux import constants, mm + +def help(): + t = """Usage: lx-kasan_mem_to_shadow [Hex memory addr] + Example: + lx-kasan_mem_to_shadow 0xffff000008eca008\n""" + gdb.write("Unrecognized command\n") + raise gdb.GdbError(t) + +class KasanMemToShadow(gdb.Command): + """Translate memory address to kasan shadow address""" + + p_ops = None + + def __init__(self): + if constants.LX_CONFIG_KASAN_GENERIC or constants.LX_CONFIG_KASAN_SW_TAGS: + super(KasanMemToShadow, self).__init__("lx-kasan_mem_to_shadow", gdb.COMMAND_SUPPORT) + + def invoke(self, args, from_tty): + if not constants.LX_CONFIG_KASAN_GENERIC or constants.LX_CONFIG_KASAN_SW_TAGS: + raise gdb.GdbError('CONFIG_KASAN_GENERIC or CONFIG_KASAN_SW_TAGS is not set') + + argv = gdb.string_to_argv(args) + if len(argv) == 1: + if self.p_ops is None: + self.p_ops = mm.page_ops().ops + addr = int(argv[0], 16) + shadow_addr = self.kasan_mem_to_shadow(addr) + gdb.write('shadow addr: 0x%x\n' % shadow_addr) + else: + help() + def kasan_mem_to_shadow(self, addr): + return (addr >> self.p_ops.KASAN_SHADOW_SCALE_SHIFT) + self.p_ops.KASAN_SHADOW_OFFSET + +KasanMemToShadow() diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index fc53cdf286f1..d4eeed4506fd 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -49,3 +49,4 @@ else: import linux.page_owner import linux.slab import linux.vmalloc + import linux.kasan -- cgit v1.2.3