All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] gdb script for kconfig and timer list
@ 2019-03-25 18:45 Stephen Boyd
  2019-03-25 18:45 ` [PATCH 1/4] scripts/gdb: Find vmlinux where it was before Stephen Boyd
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-25 18:45 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Kieran Bingham, Jan Kiszka, Jackie Liu

This is a handful of changes to the kernel's gdb scripts to do some more
debugging with kgdb. The first patch allows the vmlinux to be reloaded
from where it was specified on the command line so that this set of
scripts can be used from anywhere. The second patch adds a script to
dump the config.gz to a file on the host debugging machine. The third
patch adds some rb tree utilities and the last patch uses those rb tree
walking utilities to dump out the contents of /proc/timer_list from a
system under debug.

I'm guessing that Andrew will pick these patches up. I don't know who
maintains these gdb scripts but it looks like Andrew has been doing the
lifting recently.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Jackie Liu <liuyun01@kylinos.cn> 

Stephen Boyd (4):
  scripts/gdb: Find vmlinux where it was before
  scripts/gdb: Add kernel config dumping command
  scripts/gdb: Add rb tree iterating utilities
  scripts/gdb: Add a timer list command

 scripts/gdb/linux/config.py       |  48 ++++++++
 scripts/gdb/linux/constants.py.in |   8 ++
 scripts/gdb/linux/rbtree.py       | 169 ++++++++++++++++++++++++++
 scripts/gdb/linux/symbols.py      |   6 +-
 scripts/gdb/linux/timerlist.py    | 194 ++++++++++++++++++++++++++++++
 scripts/gdb/vmlinux-gdb.py        |   3 +
 6 files changed, 427 insertions(+), 1 deletion(-)
 create mode 100644 scripts/gdb/linux/config.py
 create mode 100644 scripts/gdb/linux/rbtree.py
 create mode 100644 scripts/gdb/linux/timerlist.py


base-commit: 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b
-- 
Sent by a computer through tubes


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] scripts/gdb: Find vmlinux where it was before
  2019-03-25 18:45 [PATCH 0/4] gdb script for kconfig and timer list Stephen Boyd
@ 2019-03-25 18:45 ` Stephen Boyd
  2019-03-25 18:45 ` [PATCH 2/4] scripts/gdb: Add kernel config dumping command Stephen Boyd
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-25 18:45 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Kieran Bingham, Jan Kiszka, Jackie Liu

If I run 'gdb <path/to/vmlinux>' and there's the vmlinux-gdb.py file
there I can properly see symbols and use the lx commands provided by the
GDB scripts. But once I run 'lx-symbols' at the command prompt, gdb
reloads the vmlinux symbols assuming that this script was run from the
directory that has vmlinux at the root. That isn't always true, but we
could just look and see what symbols were already loaded and use that
instead. Let's do that so this can work by being invoked anywhere.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Jackie Liu <liuyun01@kylinos.cn> 
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 scripts/gdb/linux/symbols.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
index 004b0ac7fa72..2f5b95f09fa0 100644
--- a/scripts/gdb/linux/symbols.py
+++ b/scripts/gdb/linux/symbols.py
@@ -139,8 +139,12 @@ lx-symbols command."""
                 saved_states.append({'breakpoint': bp, 'enabled': bp.enabled})
 
         # drop all current symbols and reload vmlinux
+        orig_vmlinux = 'vmlinux'
+        for obj in gdb.objfiles():
+            if obj.filename.endswith('vmlinux'):
+                orig_vmlinux = obj.filename
         gdb.execute("symbol-file", to_string=True)
-        gdb.execute("symbol-file vmlinux")
+        gdb.execute("symbol-file {0}".format(orig_vmlinux))
 
         self.loaded_modules = []
         module_list = modules.module_list()
-- 
Sent by a computer through tubes


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/4] scripts/gdb: Add kernel config dumping command
  2019-03-25 18:45 [PATCH 0/4] gdb script for kconfig and timer list Stephen Boyd
  2019-03-25 18:45 ` [PATCH 1/4] scripts/gdb: Find vmlinux where it was before Stephen Boyd
@ 2019-03-25 18:45 ` Stephen Boyd
  2019-03-25 18:45 ` [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities Stephen Boyd
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-25 18:45 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Kieran Bingham, Jan Kiszka, Jackie Liu

lx-configdump <file> dumps the contents of the gzipped .config to a text
file when the config is included in the kernel with CONFIG_IKCONFIG. By
default, the file written is called config.txt, but it can be any user
supplied filename as well. If the kernel config is in a module
(configs.ko), then it can be loaded along with symbols for the module
loaded with 'lx-symbols' and then this command will still work.

Obviously if you have the whole vmlinux then this can also be achieved
with scripts/extract-ikconfig, but this gdb script can be useful to
confirm that the memory contents of the config in memory and the vmlinux
contents on disk match what is expected.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Jackie Liu <liuyun01@kylinos.cn> 
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 scripts/gdb/linux/config.py | 48 +++++++++++++++++++++++++++++++++++++
 scripts/gdb/vmlinux-gdb.py  |  1 +
 2 files changed, 49 insertions(+)
 create mode 100644 scripts/gdb/linux/config.py

diff --git a/scripts/gdb/linux/config.py b/scripts/gdb/linux/config.py
new file mode 100644
index 000000000000..400f09bb2665
--- /dev/null
+++ b/scripts/gdb/linux/config.py
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright 2019 Google LLC.
+
+import gdb
+import zlib
+
+from linux import utils
+
+class LxConfigDump(gdb.Command):
+    """Output kernel config to the filename specified as the command
+       argument. Equivalent to 'zcat /proc/config.gz > config.txt' on
+       a running target"""
+
+    def __init__(self):
+        super(LxConfigDump, self).__init__("lx-configdump", gdb.COMMAND_DATA,
+                                        gdb.COMPLETE_FILENAME)
+
+    def invoke(self, arg, from_tty):
+        if len(arg) == 0:
+            filename = "config.txt"
+        else:
+            filename = arg
+
+        try:
+            py_config_ptr = gdb.parse_and_eval(
+                "kernel_config_data + 8")
+            py_config_size = gdb.parse_and_eval(
+                "sizeof(kernel_config_data) - 2 - 8 * 2")
+        except:
+            raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?")
+
+        inf = gdb.inferiors()[0]
+        zconfig_buf = utils.read_memoryview(inf, py_config_ptr,
+                                        py_config_size).tobytes()
+
+        config_buf = zlib.decompress(zconfig_buf, 16)
+        try:
+            f = open(filename, 'wb')
+        except:
+            raise gdb.GdbError("Could not open file to dump config")
+
+        f.write(config_buf)
+        f.close()
+
+        gdb.write("Dumped config to " + filename + "\n")
+
+LxConfigDump()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index 6e0b0afd888a..be0efb5dda5b 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -27,6 +27,7 @@ else:
     import linux.modules
     import linux.dmesg
     import linux.tasks
+    import linux.config
     import linux.cpus
     import linux.lists
     import linux.proc
-- 
Sent by a computer through tubes


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities
  2019-03-25 18:45 [PATCH 0/4] gdb script for kconfig and timer list Stephen Boyd
  2019-03-25 18:45 ` [PATCH 1/4] scripts/gdb: Find vmlinux where it was before Stephen Boyd
  2019-03-25 18:45 ` [PATCH 2/4] scripts/gdb: Add kernel config dumping command Stephen Boyd
@ 2019-03-25 18:45 ` Stephen Boyd
  2019-03-26  8:52   ` Kieran Bingham
  2019-03-25 18:45 ` [PATCH 4/4] scripts/gdb: Add a timer list command Stephen Boyd
  2019-03-26  8:39 ` [PATCH 0/4] gdb script for kconfig and timer list Kieran Bingham
  4 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2019-03-25 18:45 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Kieran Bingham, Jan Kiszka, Jackie Liu

Implement gdb functions for rb_first(), rb_last(), rb_next(), and
rb_prev(). These can be useful to iterate through the kernel's red-black
trees.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Jackie Liu <liuyun01@kylinos.cn> 
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 scripts/gdb/linux/rbtree.py | 169 ++++++++++++++++++++++++++++++++++++
 scripts/gdb/vmlinux-gdb.py  |   1 +
 2 files changed, 170 insertions(+)
 create mode 100644 scripts/gdb/linux/rbtree.py

diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py
new file mode 100644
index 000000000000..fd7b0b961ca1
--- /dev/null
+++ b/scripts/gdb/linux/rbtree.py
@@ -0,0 +1,169 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright 2019 Google LLC.
+
+import gdb
+
+from linux import utils
+
+rb_root_type = utils.CachedType("struct rb_root")
+rb_node_type = utils.CachedType("struct rb_node")
+
+
+def rb_first(root):
+    if root.type == rb_root_type.get_type():
+        node = node.address.cast(rb_root_type.get_type().pointer())
+    elif root.type != rb_root_type.get_type().pointer():
+        raise gdb.GdbError("Must be struct rb_root not {}"
+                .format(root.type))
+
+    node = root['rb_node']
+    if node is 0:
+        return None
+
+    while node['rb_left']:
+        node = node['rb_left']
+
+    return node
+
+def rb_last(root):
+    if root.type == rb_root_type.get_type():
+        node = node.address.cast(rb_root_type.get_type().pointer())
+    elif root.type != rb_root_type.get_type().pointer():
+        raise gdb.GdbError("Must be struct rb_root not {}"
+                .format(root.type))
+
+    node = root['rb_node']
+    if node is 0:
+        return None
+
+    while node['rb_right']:
+        node = node['rb_right']
+
+    return node
+
+def rb_parent(node):
+    parent = gdb.Value(node['__rb_parent_color'] & ~3)
+    return parent.cast(rb_node_type.get_type().pointer())
+
+def rb_empty_node(node):
+    return node['__rb_parent_color'] == node.address
+
+def rb_next(node):
+    if node.type == rb_node_type.get_type():
+        node = node.address.cast(rb_node_type.get_type().pointer())
+    elif node.type != rb_node_type.get_type().pointer():
+        raise gdb.GdbError("Must be struct rb_node not {}"
+                .format(node.type))
+
+    if rb_empty_node(node):
+        return None
+
+    if node['rb_right']:
+        node = node['rb_right']
+        while node['rb_left']:
+            node = node['rb_left']
+        return node
+
+    parent = rb_parent(node)
+    while parent and node == parent['rb_right']:
+            node = parent
+            parent = rb_parent(node)
+
+    return parent
+
+def rb_prev(node):
+    if node.type == rb_node_type.get_type():
+        node = node.address.cast(rb_node_type.get_type().pointer())
+    elif node.type != rb_node_type.get_type().pointer():
+        raise gdb.GdbError("Must be struct rb_node not {}"
+                .format(node.type))
+
+    if rb_empty_node(node):
+        return None
+
+    if node['rb_left']:
+        node = node['rb_left']
+        while node['rb_right']:
+            node = node['rb_right']
+        return node.dereference()
+
+    parent = rb_parent(node)
+    while parent and node == parent['rb_left'].dereference():
+            node = parent
+            parent = rb_parent(node)
+
+    return parent
+
+
+class LxRbFirst(gdb.Function):
+    """Lookup and return a node from an RBTree
+
+$lx_rb_first(root): Return the node at the given index.
+If index is omitted, the root node is dereferenced and returned."""
+
+    def __init__(self):
+        super(LxRbFirst, self).__init__("lx_rb_first")
+
+    def invoke(self, root):
+        result = rb_first(root)
+        if result is None:
+            raise gdb.GdbError("No entry in tree")
+
+        return result
+
+LxRbFirst()
+
+class LxRbLast(gdb.Function):
+    """Lookup and return a node from an RBTree.
+
+$lx_rb_last(root): Return the node at the given index.
+If index is omitted, the root node is dereferenced and returned."""
+
+    def __init__(self):
+        super(LxRbLast, self).__init__("lx_rb_last")
+
+    def invoke(self, root):
+        result = rb_last(root)
+        if result is None:
+            raise gdb.GdbError("No entry in tree")
+
+        return result
+
+LxRbLast()
+
+class LxRbNext(gdb.Function):
+    """Lookup and return a node from an RBTree.
+
+$lx_rb_next(node): Return the node at the given index.
+If index is omitted, the root node is dereferenced and returned."""
+
+    def __init__(self):
+        super(LxRbNext, self).__init__("lx_rb_next")
+
+    def invoke(self, node):
+        result = rb_next(node)
+        if result is None:
+            raise gdb.GdbError("No entry in tree")
+
+        return result
+
+LxRbNext()
+
+class LxRbPrev(gdb.Function):
+    """Lookup and return a node from an RBTree.
+
+$lx_rb_prev(node): Return the node at the given index.
+If index is omitted, the root node is dereferenced and returned."""
+
+    def __init__(self):
+        super(LxRbPrev, self).__init__("lx_rb_prev")
+
+    def invoke(self, node):
+        result = rb_prev(node)
+        if result is None:
+            raise gdb.GdbError("No entry in tree")
+
+        return result
+
+LxRbPrev()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index be0efb5dda5b..89e4aa4f8966 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -30,5 +30,6 @@ else:
     import linux.config
     import linux.cpus
     import linux.lists
+    import linux.rbtree
     import linux.proc
     import linux.constants
-- 
Sent by a computer through tubes


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/4] scripts/gdb: Add a timer list command
  2019-03-25 18:45 [PATCH 0/4] gdb script for kconfig and timer list Stephen Boyd
                   ` (2 preceding siblings ...)
  2019-03-25 18:45 ` [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities Stephen Boyd
@ 2019-03-25 18:45 ` Stephen Boyd
  2019-03-26  8:39 ` [PATCH 0/4] gdb script for kconfig and timer list Kieran Bingham
  4 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-25 18:45 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Kieran Bingham, Jan Kiszka, Jackie Liu

Implement a command to print the timer list, much like how
/proc/timer_list is implemented. This can be used to look at the pending
timers on a crashed system.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
Cc: Kieran Bingham <kbingham@kernel.org>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Jackie Liu <liuyun01@kylinos.cn> 
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 scripts/gdb/linux/constants.py.in |   8 ++
 scripts/gdb/linux/timerlist.py    | 194 ++++++++++++++++++++++++++++++
 scripts/gdb/vmlinux-gdb.py        |   1 +
 3 files changed, 203 insertions(+)
 create mode 100644 scripts/gdb/linux/timerlist.py

diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
index d3319a80788a..2db8183d909c 100644
--- a/scripts/gdb/linux/constants.py.in
+++ b/scripts/gdb/linux/constants.py.in
@@ -15,6 +15,7 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/of_fdt.h>
+#include <linux/hrtimer.h>
 
 /* We need to stringify expanded macros so that they can be parsed */
 
@@ -44,6 +45,9 @@ LX_VALUE(SB_DIRSYNC)
 LX_VALUE(SB_NOATIME)
 LX_VALUE(SB_NODIRATIME)
 
+/* linux/htimer.h */
+LX_GDBPARSED(hrtimer_resolution)
+
 /* linux/mount.h */
 LX_VALUE(MNT_NOSUID)
 LX_VALUE(MNT_NODEV)
@@ -56,4 +60,8 @@ LX_VALUE(MNT_RELATIME)
 LX_VALUE(OF_DT_HEADER)
 
 /* Kernel Configs */
+LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS)
+LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+LX_CONFIG(CONFIG_HIGH_RES_TIMERS)
 LX_CONFIG(CONFIG_OF)
+LX_CONFIG(CONFIG_TICK_ONESHOT)
diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py
new file mode 100644
index 000000000000..9b0111aa11a0
--- /dev/null
+++ b/scripts/gdb/linux/timerlist.py
@@ -0,0 +1,194 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright 2019 Google LLC.
+
+import gdb
+
+from linux import constants
+from linux import cpus
+from linux import rbtree
+from linux import utils
+
+timerqueue_node_type = utils.CachedType("struct timerqueue_node")
+hrtimer_type = utils.CachedType("struct hrtimer")
+
+
+def ktime_get():
+    """Returns the current time, but not very accurately
+
+    We can't read the hardware timer itself to add any nanoseconds
+    that need to be added since we last stored the time in the
+    timekeeper. But this is probably good enough for debug purposes."""
+    tk_core = gdb.parse_and_eval("&tk_core")
+
+    return tk_core['timekeeper']['tkr_mono']['base']
+
+def print_timer(rb_node, idx):
+    timerqueue = utils.container_of(rb_node, timerqueue_node_type.get_type().pointer(), "node")
+    timer = utils.container_of(timerqueue, hrtimer_type.get_type().pointer(), "node")
+
+    function = str(timer['function']).split(" ")[1].strip("<>")
+    softexpires = timer['_softexpires']
+    expires = timer['node']['expires']
+    now = ktime_get()
+
+    text = " #{}: <{}>, {}, ".format(idx, timer, function)
+    text += "S:{:02x}\n".format(int(timer['state']))
+    text += " # expires at {}-{} nsecs [in {} to {} nsecs]\n".format(softexpires,
+            expires, softexpires - now, expires - now)
+    return text
+
+def print_active_timers(base):
+    curr = base['active']['next']['node']
+    curr = curr.address.cast(rbtree.rb_node_type.get_type().pointer())
+    idx = 0
+    while curr:
+        yield print_timer(curr, idx)
+        curr = rbtree.rb_next(curr)
+        idx += 1
+
+def print_base(base):
+    text = " .base:       {}\n".format(base.address)
+    text += " .index:      {}\n".format(base['index'])
+
+    text += " .resolution: {} nsecs\n".format(constants.LX_hrtimer_resolution)
+
+    text += " .get_time:   {}\n".format(base['get_time'])
+    if constants.LX_CONFIG_HIGH_RES_TIMERS:
+        text += "  .offset:     {} nsecs\n".format(base['offset'])
+    text += "active timers:\n"
+    text += "".join([x for x in print_active_timers(base)])
+    return text
+
+def print_cpu(hrtimer_bases, cpu, max_clock_bases):
+    cpu_base = cpus.per_cpu(hrtimer_bases, cpu)
+    jiffies = gdb.parse_and_eval("jiffies")
+    tick_sched_ptr = gdb.parse_and_eval("&tick_cpu_sched")
+    ts = cpus.per_cpu(tick_sched_ptr, cpu)
+
+    text = "cpu: {}\n".format(cpu)
+    for i in xrange(max_clock_bases):
+        text += " clock {}:\n".format(i)
+        text += print_base(cpu_base['clock_base'][i])
+        if constants.LX_CONFIG_HIGH_RES_TIMERS:
+            text += """  .expires_next   : {} nsecs
+  .hres_active    : {}
+  .nr_events      : {}
+  .nr_retries     : {}
+  .nr_hangs       : {}
+  .max_hang_time  : {}
+""".format(cpu_base['expires_next'],
+           cpu_base['hres_active'],
+           cpu_base['nr_events'],
+           cpu_base['nr_retries'],
+           cpu_base['nr_hangs'],
+           cpu_base['max_hang_time'])
+        if constants.LX_CONFIG_TICK_ONESHOT:
+            text += """  .nohz_mode      : {}
+  .last_tick      : {} nsecs
+  .tick_stopped   : {}
+  .idle_jiffies   : {}
+  .idle_calls     : {}
+  .idle_sleeps    : {}
+  .idle_entrytime : {} nsecs
+  .idle_waketime  : {} nsecs
+  .idle_exittime  : {} nsecs
+  .idle_sleeptime : {} nsecs
+  .iowait_sleeptime: {} nsecs
+  .last_jiffies   : {}
+  .next_timer     : {}
+  .idle_expires   : {} nsecs
+jiffies: {}
+""".format(ts['nohz_mode'],
+           ts['last_tick'],
+           ts['tick_stopped'],
+           ts['idle_jiffies'],
+           ts['idle_calls'],
+           ts['idle_sleeps'],
+           ts['idle_entrytime'],
+           ts['idle_waketime'],
+           ts['idle_exittime'],
+           ts['idle_sleeptime'],
+           ts['iowait_sleeptime'],
+           ts['last_jiffies'],
+           ts['next_timer'],
+           ts['idle_expires'],
+           jiffies)
+
+        text += "\n"
+
+    return text
+
+def print_tickdevice(td, cpu):
+    dev = td['evtdev']
+    text = "Tick Device: mode:     {}\n".format(td['mode'])
+    if cpu < 0:
+            text += "Broadcast device\n"
+    else:
+            text += "Per CPU device: {}\n".format(cpu)
+
+    text += "Clock Event Device: "
+    if dev == 0:
+            text += "<NULL>\n"
+            return text
+
+    text += "{}\n".format(dev['name'])
+    text += " max_delta_ns:   {}\n".format(dev['max_delta_ns'])
+    text += " min_delta_ns:   {}\n".format(dev['min_delta_ns'])
+    text += " mult:           {}\n".format(dev['mult'])
+    text += " shift:          {}\n".format(dev['shift'])
+    text += " mode:           {}\n".format(dev['state_use_accessors'])
+    text += " next_event:     {} nsecs\n".format(dev['next_event'])
+
+    text += " set_next_event: {}\n".format(dev['set_next_event'])
+
+    members = [('set_state_shutdown', " shutdown: {}\n"),
+               ('set_state_periodic', " periodic: {}\n"),
+               ('set_state_oneshot', " oneshot:  {}\n"),
+               ('set_state_oneshot_stopped', " oneshot stopped: {}\n"),
+               ('tick_resume', " resume:   {}\n"),
+              ]
+    for (member, fmt) in members:
+        if dev[member]:
+            text += fmt.format(dev[member])
+
+    text += " event_handler:  {}\n".format(dev['event_handler'])
+    text += " retries:        {}\n".format(dev['retries'])
+
+    return text
+
+class LxTimerList(gdb.Command):
+    """Print /proc/timer_list"""
+
+    def __init__(self):
+        super(LxTimerList, self).__init__("lx-timerlist", gdb.COMMAND_DATA)
+
+    def invoke(self, arg, from_tty):
+        hrtimer_bases = gdb.parse_and_eval("&hrtimer_bases")
+        max_clock_bases = gdb.parse_and_eval("HRTIMER_MAX_CLOCK_BASES")
+
+        text = "Timer List Version: gdb scripts\n"
+        text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format(max_clock_bases)
+        text += "now at {} nsecs\n".format(ktime_get())
+
+        for cpu in cpus.each_online_cpu():
+            text += print_cpu(hrtimer_bases, cpu, max_clock_bases)
+
+        if constants.LX_CONFIG_GENERIC_CLOCKEVENTS:
+            if constants.LX_CONFIG_GENERIC_CLOCKEVENTS_BROADCAST:
+                bc_dev = gdb.parse_and_eval("&tick_broadcast_device")
+                text += print_tickdevice(bc_dev, -1)
+                text += "\n"
+                mask = gdb.parse_and_eval("tick_broadcast_mask")
+                text += "tick_broadcast_mask: {}\n".format(mask) # TODO: format properly
+                if constants.LX_CONFIG_TICK_ONESHOT:
+                    mask = gdb.parse_and_eval("tick_broadcast_oneshot_mask")
+                    text += "tick_broadcast_oneshot_mask: {}\n".format(mask) # TODO: format properly
+                text += "\n"
+
+            tick_cpu_devices = gdb.parse_and_eval("&tick_cpu_device")
+            text += "\n".join([print_tickdevice(cpus.per_cpu(tick_cpu_devices, cpu), cpu) for cpu in cpus.each_online_cpu()])
+
+        gdb.write(text)
+
+LxTimerList()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index 89e4aa4f8966..033578cc4cd7 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -33,3 +33,4 @@ else:
     import linux.rbtree
     import linux.proc
     import linux.constants
+    import linux.timerlist
-- 
Sent by a computer through tubes


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] gdb script for kconfig and timer list
  2019-03-25 18:45 [PATCH 0/4] gdb script for kconfig and timer list Stephen Boyd
                   ` (3 preceding siblings ...)
  2019-03-25 18:45 ` [PATCH 4/4] scripts/gdb: Add a timer list command Stephen Boyd
@ 2019-03-26  8:39 ` Kieran Bingham
  2019-03-26 20:35   ` Stephen Boyd
  4 siblings, 1 reply; 12+ messages in thread
From: Kieran Bingham @ 2019-03-26  8:39 UTC (permalink / raw)
  To: Stephen Boyd, Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jan Kiszka, Jackie Liu

Hi Stephen,

Thank you for these patches,

Could you check them through with PEP8 please?

While we are not entirely "pep8 clean", Your series adds the following
warnings:

linux/config.py:10:1: E302 expected 2 blank lines, found 1
linux/config.py:17:41: E128 continuation line under-indented for visual
indent
linux/config.py:30:9: E722 do not use bare 'except'
linux/config.py:35:41: E128 continuation line under-indented for visual
indent
linux/config.py:40:9: E722 do not use bare 'except'
linux/config.py:48:1: E305 expected 2 blank lines after class or
function definition, found 1

linux/rbtree.py:18:17: E128 continuation line under-indented for visual
indent
linux/rbtree.py:29:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:34:17: E128 continuation line under-indented for visual
indent
linux/rbtree.py:45:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:49:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:52:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:57:17: E128 continuation line under-indented for visual
indent
linux/rbtree.py:75:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:80:17: E128 continuation line under-indented for visual
indent
linux/rbtree.py:115:1: E305 expected 2 blank lines after class or
function definition, found 1
linux/rbtree.py:117:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:133:1: E305 expected 2 blank lines after class or
function definition, found 1
linux/rbtree.py:135:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:151:1: E305 expected 2 blank lines after class or
function definition, found 1
linux/rbtree.py:153:1: E302 expected 2 blank lines, found 1
linux/rbtree.py:169:1: E305 expected 2 blank lines after class or
function definition, found 1

linux/timerlist.py:26:1: E302 expected 2 blank lines, found 1
linux/timerlist.py:27:80: E501 line too long (95 > 79 characters)
linux/timerlist.py:28:80: E501 line too long (85 > 79 characters)
linux/timerlist.py:37:80: E501 line too long (81 > 79 characters)
linux/timerlist.py:38:13: E128 continuation line under-indented for
visual indent
linux/timerlist.py:41:1: E302 expected 2 blank lines, found 1
linux/timerlist.py:50:1: E302 expected 2 blank lines, found 1
linux/timerlist.py:63:1: E302 expected 2 blank lines, found 1
linux/timerlist.py:81:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:82:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:83:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:84:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:85:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:103:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:104:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:105:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:106:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:107:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:108:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:109:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:110:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:111:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:112:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:113:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:114:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:115:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:116:12: E122 continuation line missing indentation or
outdented
linux/timerlist.py:122:1: E302 expected 2 blank lines, found 1
linux/timerlist.py:150:15: E124 closing bracket does not match visual
indentation
linux/timerlist.py:160:1: E302 expected 2 blank lines, found 1
linux/timerlist.py:183:65: E261 at least two spaces before inline comment
linux/timerlist.py:183:80: E501 line too long (88 > 79 characters)
linux/timerlist.py:186:77: E261 at least two spaces before inline comment
linux/timerlist.py:186:80: E501 line too long (100 > 79 characters)
linux/timerlist.py:190:80: E501 line too long (125 > 79 characters)
linux/timerlist.py:194:1: E305 expected 2 blank lines after class or
function definition, found 1

--
Regards

Kieran



On 25/03/2019 18:45, Stephen Boyd wrote:
> This is a handful of changes to the kernel's gdb scripts to do some more
> debugging with kgdb. The first patch allows the vmlinux to be reloaded
> from where it was specified on the command line so that this set of
> scripts can be used from anywhere. The second patch adds a script to
> dump the config.gz to a file on the host debugging machine. The third
> patch adds some rb tree utilities and the last patch uses those rb tree
> walking utilities to dump out the contents of /proc/timer_list from a
> system under debug.
> 
> I'm guessing that Andrew will pick these patches up. I don't know who
> maintains these gdb scripts but it looks like Andrew has been doing the
> lifting recently.
> 
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
> Cc: Kieran Bingham <kbingham@kernel.org>
> Cc: Jan Kiszka <jan.kiszka@siemens.com>
> Cc: Jackie Liu <liuyun01@kylinos.cn> 
> 
> Stephen Boyd (4):
>   scripts/gdb: Find vmlinux where it was before
>   scripts/gdb: Add kernel config dumping command
>   scripts/gdb: Add rb tree iterating utilities
>   scripts/gdb: Add a timer list command
> 
>  scripts/gdb/linux/config.py       |  48 ++++++++
>  scripts/gdb/linux/constants.py.in |   8 ++
>  scripts/gdb/linux/rbtree.py       | 169 ++++++++++++++++++++++++++
>  scripts/gdb/linux/symbols.py      |   6 +-
>  scripts/gdb/linux/timerlist.py    | 194 ++++++++++++++++++++++++++++++
>  scripts/gdb/vmlinux-gdb.py        |   3 +
>  6 files changed, 427 insertions(+), 1 deletion(-)
>  create mode 100644 scripts/gdb/linux/config.py
>  create mode 100644 scripts/gdb/linux/rbtree.py
>  create mode 100644 scripts/gdb/linux/timerlist.py
> 
> 
> base-commit: 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b
> 


-- 
--
Kieran

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities
  2019-03-25 18:45 ` [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities Stephen Boyd
@ 2019-03-26  8:52   ` Kieran Bingham
  2019-03-26 17:05     ` Stephen Boyd
  0 siblings, 1 reply; 12+ messages in thread
From: Kieran Bingham @ 2019-03-26  8:52 UTC (permalink / raw)
  To: Stephen Boyd, Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jan Kiszka, Jackie Liu

Hi Stephen,

On 25/03/2019 18:45, Stephen Boyd wrote:
> Implement gdb functions for rb_first(), rb_last(), rb_next(), and
> rb_prev(). These can be useful to iterate through the kernel's red-black
> trees.

I definitely approve of getting data-structure helpers into scripts/gdb,
as it will greatly assist debug options but my last attempt to do this
was with the radix-tree which I had to give up on as the internals were
changing rapidly and caused continuous breakage to the helpers.

Do you foresee any similar issue here? Or is the corresponding RB code
in the kernel fairly 'stable'?


Please could we make sure whomever maintains the RBTree code is aware of
the python implementation?

That said, MAINTAINERS doesn't actually seem to list any ownership over
the rb-tree code, and get_maintainers.pl [0] seems to be pointing at
Andrew as the probable route in for that code so perhaps that's already
in place :D



[0]
> ./scripts/get_maintainer.pl -f ./include/linux/rbtree*
> Andrew Morton <akpm@linux-foundation.org> (commit_signer:3/2=100%,commit_signer:2/1=100%)
> Sebastian Andrzej Siewior <bigeasy@linutronix.de> (commit_signer:1/2=50%,authored:1/2=50%,added_lines:1/3=33%,commit_signer:1/1=100%,authored:1/1=100%,added_lines:1/1=100%)
> Wei Yang <richard.weiyang@gmail.com> (commit_signer:1/2=50%,authored:1/2=50%,added_lines:2/3=67%,removed_lines:2/2=100%)
> linux-kernel@vger.kernel.org (open list)

--
Regards

Kieran


> 
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Nikolay Borisov <n.borisov.lkml@gmail.com>
> Cc: Kieran Bingham <kbingham@kernel.org>
> Cc: Jan Kiszka <jan.kiszka@siemens.com>
> Cc: Jackie Liu <liuyun01@kylinos.cn> 
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  scripts/gdb/linux/rbtree.py | 169 ++++++++++++++++++++++++++++++++++++
>  scripts/gdb/vmlinux-gdb.py  |   1 +
>  2 files changed, 170 insertions(+)
>  create mode 100644 scripts/gdb/linux/rbtree.py
> 
> diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py
> new file mode 100644
> index 000000000000..fd7b0b961ca1
> --- /dev/null
> +++ b/scripts/gdb/linux/rbtree.py
> @@ -0,0 +1,169 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Copyright 2019 Google LLC.
> +
> +import gdb
> +
> +from linux import utils
> +
> +rb_root_type = utils.CachedType("struct rb_root")
> +rb_node_type = utils.CachedType("struct rb_node")
> +
> +
> +def rb_first(root):
> +    if root.type == rb_root_type.get_type():
> +        node = node.address.cast(rb_root_type.get_type().pointer())
> +    elif root.type != rb_root_type.get_type().pointer():
> +        raise gdb.GdbError("Must be struct rb_root not {}"
> +                .format(root.type))
> +
> +    node = root['rb_node']
> +    if node is 0:
> +        return None
> +
> +    while node['rb_left']:
> +        node = node['rb_left']
> +
> +    return node
> +
> +def rb_last(root):
> +    if root.type == rb_root_type.get_type():
> +        node = node.address.cast(rb_root_type.get_type().pointer())
> +    elif root.type != rb_root_type.get_type().pointer():
> +        raise gdb.GdbError("Must be struct rb_root not {}"
> +                .format(root.type))
> +
> +    node = root['rb_node']
> +    if node is 0:
> +        return None
> +
> +    while node['rb_right']:
> +        node = node['rb_right']
> +
> +    return node
> +
> +def rb_parent(node):
> +    parent = gdb.Value(node['__rb_parent_color'] & ~3)
> +    return parent.cast(rb_node_type.get_type().pointer())
> +
> +def rb_empty_node(node):
> +    return node['__rb_parent_color'] == node.address
> +
> +def rb_next(node):
> +    if node.type == rb_node_type.get_type():
> +        node = node.address.cast(rb_node_type.get_type().pointer())
> +    elif node.type != rb_node_type.get_type().pointer():
> +        raise gdb.GdbError("Must be struct rb_node not {}"
> +                .format(node.type))
> +
> +    if rb_empty_node(node):
> +        return None
> +
> +    if node['rb_right']:
> +        node = node['rb_right']
> +        while node['rb_left']:
> +            node = node['rb_left']
> +        return node
> +
> +    parent = rb_parent(node)
> +    while parent and node == parent['rb_right']:
> +            node = parent
> +            parent = rb_parent(node)
> +
> +    return parent
> +
> +def rb_prev(node):
> +    if node.type == rb_node_type.get_type():
> +        node = node.address.cast(rb_node_type.get_type().pointer())
> +    elif node.type != rb_node_type.get_type().pointer():
> +        raise gdb.GdbError("Must be struct rb_node not {}"
> +                .format(node.type))
> +
> +    if rb_empty_node(node):
> +        return None
> +
> +    if node['rb_left']:
> +        node = node['rb_left']
> +        while node['rb_right']:
> +            node = node['rb_right']
> +        return node.dereference()
> +
> +    parent = rb_parent(node)
> +    while parent and node == parent['rb_left'].dereference():
> +            node = parent
> +            parent = rb_parent(node)
> +
> +    return parent
> +
> +
> +class LxRbFirst(gdb.Function):
> +    """Lookup and return a node from an RBTree
> +
> +$lx_rb_first(root): Return the node at the given index.
> +If index is omitted, the root node is dereferenced and returned."""
> +
> +    def __init__(self):
> +        super(LxRbFirst, self).__init__("lx_rb_first")
> +
> +    def invoke(self, root):
> +        result = rb_first(root)
> +        if result is None:
> +            raise gdb.GdbError("No entry in tree")
> +
> +        return result
> +
> +LxRbFirst()
> +
> +class LxRbLast(gdb.Function):
> +    """Lookup and return a node from an RBTree.
> +
> +$lx_rb_last(root): Return the node at the given index.
> +If index is omitted, the root node is dereferenced and returned."""
> +
> +    def __init__(self):
> +        super(LxRbLast, self).__init__("lx_rb_last")
> +
> +    def invoke(self, root):
> +        result = rb_last(root)
> +        if result is None:
> +            raise gdb.GdbError("No entry in tree")
> +
> +        return result
> +
> +LxRbLast()
> +
> +class LxRbNext(gdb.Function):
> +    """Lookup and return a node from an RBTree.
> +
> +$lx_rb_next(node): Return the node at the given index.
> +If index is omitted, the root node is dereferenced and returned."""
> +
> +    def __init__(self):
> +        super(LxRbNext, self).__init__("lx_rb_next")
> +
> +    def invoke(self, node):
> +        result = rb_next(node)
> +        if result is None:
> +            raise gdb.GdbError("No entry in tree")
> +
> +        return result
> +
> +LxRbNext()
> +
> +class LxRbPrev(gdb.Function):
> +    """Lookup and return a node from an RBTree.
> +
> +$lx_rb_prev(node): Return the node at the given index.
> +If index is omitted, the root node is dereferenced and returned."""
> +
> +    def __init__(self):
> +        super(LxRbPrev, self).__init__("lx_rb_prev")
> +
> +    def invoke(self, node):
> +        result = rb_prev(node)
> +        if result is None:
> +            raise gdb.GdbError("No entry in tree")
> +
> +        return result
> +
> +LxRbPrev()
> diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
> index be0efb5dda5b..89e4aa4f8966 100644
> --- a/scripts/gdb/vmlinux-gdb.py
> +++ b/scripts/gdb/vmlinux-gdb.py
> @@ -30,5 +30,6 @@ else:
>      import linux.config
>      import linux.cpus
>      import linux.lists
> +    import linux.rbtree
>      import linux.proc
>      import linux.constants
> 


-- 
--
Kieran

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities
  2019-03-26  8:52   ` Kieran Bingham
@ 2019-03-26 17:05     ` Stephen Boyd
  2019-03-26 17:21       ` Jan Kiszka
  2019-03-27 10:37       ` Kieran Bingham
  0 siblings, 2 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-26 17:05 UTC (permalink / raw)
  To: Andrew Morton, Kieran Bingham
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jan Kiszka, Jackie Liu

Quoting Kieran Bingham (2019-03-26 01:52:10)
> Hi Stephen,
> 
> On 25/03/2019 18:45, Stephen Boyd wrote:
> > Implement gdb functions for rb_first(), rb_last(), rb_next(), and
> > rb_prev(). These can be useful to iterate through the kernel's red-black
> > trees.
> 
> I definitely approve of getting data-structure helpers into scripts/gdb,
> as it will greatly assist debug options but my last attempt to do this
> was with the radix-tree which I had to give up on as the internals were
> changing rapidly and caused continuous breakage to the helpers.

Thanks for the background on radix-tree. I haven't looked at that yet,
but I suppose I'll want to have that too at some point.

> 
> Do you foresee any similar issue here? Or is the corresponding RB code
> in the kernel fairly 'stable'?
> 
> 
> Please could we make sure whomever maintains the RBTree code is aware of
> the python implementation?
> 
> That said, MAINTAINERS doesn't actually seem to list any ownership over
> the rb-tree code, and get_maintainers.pl [0] seems to be pointing at
> Andrew as the probable route in for that code so perhaps that's already
> in place :D

I don't think that the rb tree implementation is going to change. It
feels similar to the list API. I suppose this problem of keeping things
in sync is a more general problem than just data-structures changing.
The only solution I can offer is to have more testing and usage of these
scripts. Unless gdb can "simulate" or run arbitrary code for us then I
think we're stuck reimplementing kernel internal code in gdb scripts so
that we can get debug info out.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities
  2019-03-26 17:05     ` Stephen Boyd
@ 2019-03-26 17:21       ` Jan Kiszka
  2019-03-26 20:39         ` Stephen Boyd
  2019-03-27 10:37       ` Kieran Bingham
  1 sibling, 1 reply; 12+ messages in thread
From: Jan Kiszka @ 2019-03-26 17:21 UTC (permalink / raw)
  To: Stephen Boyd, Andrew Morton, Kieran Bingham
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jackie Liu

On 26.03.19 18:05, Stephen Boyd wrote:
> Quoting Kieran Bingham (2019-03-26 01:52:10)
>> Hi Stephen,
>>
>> On 25/03/2019 18:45, Stephen Boyd wrote:
>>> Implement gdb functions for rb_first(), rb_last(), rb_next(), and
>>> rb_prev(). These can be useful to iterate through the kernel's red-black
>>> trees.
>>
>> I definitely approve of getting data-structure helpers into scripts/gdb,
>> as it will greatly assist debug options but my last attempt to do this
>> was with the radix-tree which I had to give up on as the internals were
>> changing rapidly and caused continuous breakage to the helpers.
> 
> Thanks for the background on radix-tree. I haven't looked at that yet,
> but I suppose I'll want to have that too at some point.
> 
>>
>> Do you foresee any similar issue here? Or is the corresponding RB code
>> in the kernel fairly 'stable'?
>>
>>
>> Please could we make sure whomever maintains the RBTree code is aware of
>> the python implementation?
>>
>> That said, MAINTAINERS doesn't actually seem to list any ownership over
>> the rb-tree code, and get_maintainers.pl [0] seems to be pointing at
>> Andrew as the probable route in for that code so perhaps that's already
>> in place :D
> 
> I don't think that the rb tree implementation is going to change. It
> feels similar to the list API. I suppose this problem of keeping things
> in sync is a more general problem than just data-structures changing.
> The only solution I can offer is to have more testing and usage of these
> scripts. Unless gdb can "simulate" or run arbitrary code for us then I
> think we're stuck reimplementing kernel internal code in gdb scripts so
> that we can get debug info out.
> 

Could we possibly leave some link in form of comment in the related headers or 
implementations? Won't magically solve the problem but at least increase changes 
that author actually read them when they start changing the C implementations.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] gdb script for kconfig and timer list
  2019-03-26  8:39 ` [PATCH 0/4] gdb script for kconfig and timer list Kieran Bingham
@ 2019-03-26 20:35   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-26 20:35 UTC (permalink / raw)
  To: Andrew Morton, Kieran Bingham
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jan Kiszka, Jackie Liu

Quoting Kieran Bingham (2019-03-26 01:39:43)
> Hi Stephen,
> 
> Thank you for these patches,
> 
> Could you check them through with PEP8 please?
> 
> While we are not entirely "pep8 clean", Your series adds the following
> warnings:

Sure. I didn't know what was desired here because python in the kernel
is not checked by anything like checkpatch. I've fixed it all up and
things got a little shorter so it must be better! Now to test it out.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities
  2019-03-26 17:21       ` Jan Kiszka
@ 2019-03-26 20:39         ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2019-03-26 20:39 UTC (permalink / raw)
  To: Andrew Morton, Jan Kiszka, Kieran Bingham
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jackie Liu

Quoting Jan Kiszka (2019-03-26 10:21:21)
> On 26.03.19 18:05, Stephen Boyd wrote:
> > Quoting Kieran Bingham (2019-03-26 01:52:10)
> >>
> >> Do you foresee any similar issue here? Or is the corresponding RB code
> >> in the kernel fairly 'stable'?
> >>
> >>
> >> Please could we make sure whomever maintains the RBTree code is aware of
> >> the python implementation?
> >>
> >> That said, MAINTAINERS doesn't actually seem to list any ownership over
> >> the rb-tree code, and get_maintainers.pl [0] seems to be pointing at
> >> Andrew as the probable route in for that code so perhaps that's already
> >> in place :D
> > 
> > I don't think that the rb tree implementation is going to change. It
> > feels similar to the list API. I suppose this problem of keeping things
> > in sync is a more general problem than just data-structures changing.
> > The only solution I can offer is to have more testing and usage of these
> > scripts. Unless gdb can "simulate" or run arbitrary code for us then I
> > think we're stuck reimplementing kernel internal code in gdb scripts so
> > that we can get debug info out.
> > 
> 
> Could we possibly leave some link in form of comment in the related headers or 
> implementations? Won't magically solve the problem but at least increase changes 
> that author actually read them when they start changing the C implementations.
> 

Sure. Can you propose some sort of patch against the 'list'
implementation for this? I'd like to just use whatever policy is decided
here.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities
  2019-03-26 17:05     ` Stephen Boyd
  2019-03-26 17:21       ` Jan Kiszka
@ 2019-03-27 10:37       ` Kieran Bingham
  1 sibling, 0 replies; 12+ messages in thread
From: Kieran Bingham @ 2019-03-27 10:37 UTC (permalink / raw)
  To: Stephen Boyd, Andrew Morton
  Cc: linux-kernel, Masahiro Yamada, Douglas Anderson, Nikolay Borisov,
	Jan Kiszka, Jackie Liu

Hi Stephen,

On 26/03/2019 17:05, Stephen Boyd wrote:
> Quoting Kieran Bingham (2019-03-26 01:52:10)
>> Hi Stephen,
>>
>> On 25/03/2019 18:45, Stephen Boyd wrote:
>>> Implement gdb functions for rb_first(), rb_last(), rb_next(), and
>>> rb_prev(). These can be useful to iterate through the kernel's red-black
>>> trees.
>>
>> I definitely approve of getting data-structure helpers into scripts/gdb,
>> as it will greatly assist debug options but my last attempt to do this
>> was with the radix-tree which I had to give up on as the internals were
>> changing rapidly and caused continuous breakage to the helpers.
> 
> Thanks for the background on radix-tree. I haven't looked at that yet,
> but I suppose I'll want to have that too at some point.

Sure, it will be useful to get going again, if you get round to it -
feel free to either dig out my old patches from the list, or
git-history. (I believe they actually made it into the kernel but I had
to revert them because of the breakage, and no time to continue that
development).

Or of course - start from scratch might also be a good option :D


>> Do you foresee any similar issue here? Or is the corresponding RB code
>> in the kernel fairly 'stable'?
>>
>>
>> Please could we make sure whomever maintains the RBTree code is aware of
>> the python implementation?
>>
>> That said, MAINTAINERS doesn't actually seem to list any ownership over
>> the rb-tree code, and get_maintainers.pl [0] seems to be pointing at
>> Andrew as the probable route in for that code so perhaps that's already
>> in place :D
> 
> I don't think that the rb tree implementation is going to change. It
> feels similar to the list API. I suppose this problem of keeping things
> in sync is a more general problem than just data-structures changing.
> The only solution I can offer is to have more testing and usage of these
> scripts. Unless gdb can "simulate" or run arbitrary code for us then I
> think we're stuck reimplementing kernel internal code in gdb scripts so
> that we can get debug info out.

I agree - RB seems a lot more stable than the radix-tree was back when I
tried to mirror that implementation.

I would hope at some point we could get some automated tests going for
scripts/gdb as we see more and more functionality.

Everything should be automatable using GDB hooked up to QEmu.

GDB can 'run' arbitrary functions - but it's not a good idea as we won't
know the state of the target, and of course in the case of crash-dump
examination - the target won't even exist.

Anyway, I'm glad this is all useful to you - let us know if there's
anything we can do to help. Myself and Jan are trying to take care of
scripts/gdb - but there's not a lot of active development of new
features currently - so I'm very pleased to see your contributions !


--
Kieran

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-03-27 10:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-25 18:45 [PATCH 0/4] gdb script for kconfig and timer list Stephen Boyd
2019-03-25 18:45 ` [PATCH 1/4] scripts/gdb: Find vmlinux where it was before Stephen Boyd
2019-03-25 18:45 ` [PATCH 2/4] scripts/gdb: Add kernel config dumping command Stephen Boyd
2019-03-25 18:45 ` [PATCH 3/4] scripts/gdb: Add rb tree iterating utilities Stephen Boyd
2019-03-26  8:52   ` Kieran Bingham
2019-03-26 17:05     ` Stephen Boyd
2019-03-26 17:21       ` Jan Kiszka
2019-03-26 20:39         ` Stephen Boyd
2019-03-27 10:37       ` Kieran Bingham
2019-03-25 18:45 ` [PATCH 4/4] scripts/gdb: Add a timer list command Stephen Boyd
2019-03-26  8:39 ` [PATCH 0/4] gdb script for kconfig and timer list Kieran Bingham
2019-03-26 20:35   ` Stephen Boyd

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.