diff options
Diffstat (limited to 'scripts/gdb')
-rw-r--r-- | scripts/gdb/linux/clk.py | 76 | ||||
-rw-r--r-- | scripts/gdb/linux/config.py | 44 | ||||
-rw-r--r-- | scripts/gdb/linux/constants.py.in | 17 | ||||
-rw-r--r-- | scripts/gdb/linux/cpus.py | 1 | ||||
-rw-r--r-- | scripts/gdb/linux/lists.py | 26 | ||||
-rw-r--r-- | scripts/gdb/linux/proc.py | 10 | ||||
-rw-r--r-- | scripts/gdb/linux/rbtree.py | 177 | ||||
-rw-r--r-- | scripts/gdb/linux/symbols.py | 6 | ||||
-rw-r--r-- | scripts/gdb/linux/tasks.py | 2 | ||||
-rw-r--r-- | scripts/gdb/linux/timerlist.py | 219 | ||||
-rw-r--r-- | scripts/gdb/linux/utils.py | 7 | ||||
-rw-r--r-- | scripts/gdb/vmlinux-gdb.py | 4 |
12 files changed, 579 insertions, 10 deletions
diff --git a/scripts/gdb/linux/clk.py b/scripts/gdb/linux/clk.py new file mode 100644 index 000000000000..061aecfa294e --- /dev/null +++ b/scripts/gdb/linux/clk.py @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) NXP 2019 + +import gdb +import sys + +from linux import utils, lists, constants + +clk_core_type = utils.CachedType("struct clk_core") + + +def clk_core_for_each_child(hlist_head): + return lists.hlist_for_each_entry(hlist_head, + clk_core_type.get_type().pointer(), "child_node") + + +class LxClkSummary(gdb.Command): + """Print clk tree summary + +Output is a subset of /sys/kernel/debug/clk/clk_summary + +No calls are made during printing, instead a (c) if printed after values which +are cached and potentially out of date""" + + def __init__(self): + super(LxClkSummary, self).__init__("lx-clk-summary", gdb.COMMAND_DATA) + + def show_subtree(self, clk, level): + gdb.write("%*s%-*s %7d %8d %8d %11lu%s\n" % ( + level * 3 + 1, "", + 30 - level * 3, + clk['name'].string(), + clk['enable_count'], + clk['prepare_count'], + clk['protect_count'], + clk['rate'], + '(c)' if clk['flags'] & constants.LX_CLK_GET_RATE_NOCACHE else ' ')) + + for child in clk_core_for_each_child(clk['children']): + self.show_subtree(child, level + 1) + + def invoke(self, arg, from_tty): + gdb.write(" enable prepare protect \n") + gdb.write(" clock count count count rate \n") + gdb.write("------------------------------------------------------------------------\n") + for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_root_list")): + self.show_subtree(clk, 0) + for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_orphan_list")): + self.show_subtree(clk, 0) + + +LxClkSummary() + + +class LxClkCoreLookup(gdb.Function): + """Find struct clk_core by name""" + + def __init__(self): + super(LxClkCoreLookup, self).__init__("lx_clk_core_lookup") + + def lookup_hlist(self, hlist_head, name): + for child in clk_core_for_each_child(hlist_head): + if child['name'].string() == name: + return child + result = self.lookup_hlist(child['children'], name) + if result: + return result + + def invoke(self, name): + name = name.string() + return (self.lookup_hlist(gdb.parse_and_eval("clk_root_list"), name) or + self.lookup_hlist(gdb.parse_and_eval("clk_orphan_list"), name)) + + +LxClkCoreLookup() diff --git a/scripts/gdb/linux/config.py b/scripts/gdb/linux/config.py new file mode 100644 index 000000000000..90e1565b1967 --- /dev/null +++ b/scripts/gdb/linux/config.py @@ -0,0 +1,44 @@ +# 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) - 1 - 8 * 2") + except gdb.error as e: + 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) + with open(filename, 'wb') as f: + f.write(config_buf) + + gdb.write("Dumped config to " + filename + "\n") + + +LxConfigDump() diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index d3319a80788a..1d73083da6cb 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -12,9 +12,12 @@ * */ +#include <linux/clk-provider.h> #include <linux/fs.h> +#include <linux/hrtimer.h> #include <linux/mount.h> #include <linux/of_fdt.h> +#include <linux/threads.h> /* We need to stringify expanded macros so that they can be parsed */ @@ -36,6 +39,9 @@ import gdb +/* linux/clk-provider.h */ +LX_GDBPARSED(CLK_GET_RATE_NOCACHE) + /* linux/fs.h */ LX_VALUE(SB_RDONLY) LX_VALUE(SB_SYNCHRONOUS) @@ -44,6 +50,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) @@ -52,8 +61,16 @@ LX_VALUE(MNT_NOATIME) LX_VALUE(MNT_NODIRATIME) LX_VALUE(MNT_RELATIME) +/* linux/threads.h */ +LX_VALUE(NR_CPUS) + /* linux/of_fdt.h> */ 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_NR_CPUS) LX_CONFIG(CONFIG_OF) +LX_CONFIG(CONFIG_TICK_ONESHOT) diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index ca11e8df31b6..008e62f3190d 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -135,6 +135,7 @@ and can help identify the state of hotplugged CPUs""" gdb.write("Online CPUs : {}\n".format(list(each_online_cpu()))) gdb.write("Active CPUs : {}\n".format(list(each_active_cpu()))) + LxCpus() diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py index 2f335fbd86fd..c487ddf09d38 100644 --- a/scripts/gdb/linux/lists.py +++ b/scripts/gdb/linux/lists.py @@ -16,13 +16,15 @@ import gdb from linux import utils list_head = utils.CachedType("struct list_head") +hlist_head = utils.CachedType("struct hlist_head") +hlist_node = utils.CachedType("struct hlist_node") def list_for_each(head): if head.type == list_head.get_type().pointer(): head = head.dereference() elif head.type != list_head.get_type(): - raise gdb.GdbError("Must be struct list_head not {}" + raise TypeError("Must be struct list_head not {}" .format(head.type)) node = head['next'].dereference() @@ -33,9 +35,24 @@ def list_for_each(head): def list_for_each_entry(head, gdbtype, member): for node in list_for_each(head): - if node.type != list_head.get_type().pointer(): - raise TypeError("Type {} found. Expected struct list_head *." - .format(node.type)) + yield utils.container_of(node, gdbtype, member) + + +def hlist_for_each(head): + if head.type == hlist_head.get_type().pointer(): + head = head.dereference() + elif head.type != hlist_head.get_type(): + raise TypeError("Must be struct hlist_head not {}" + .format(head.type)) + + node = head['first'].dereference() + while node.address: + yield node.address + node = node['next'].dereference() + + +def hlist_for_each_entry(head, gdbtype, member): + for node in hlist_for_each(head): yield utils.container_of(node, gdbtype, member) @@ -110,4 +127,5 @@ class LxListChk(gdb.Command): raise gdb.GdbError("lx-list-check takes one argument") list_check(gdb.parse_and_eval(argv[0])) + LxListChk() diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 2f01a958eb22..6a56bba233a9 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -29,6 +29,7 @@ class LxCmdLine(gdb.Command): def invoke(self, arg, from_tty): gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n") + LxCmdLine() @@ -43,6 +44,7 @@ class LxVersion(gdb.Command): # linux_banner should contain a newline gdb.write(gdb.parse_and_eval("(char *)linux_banner").string()) + LxVersion() @@ -86,6 +88,7 @@ Equivalent to cat /proc/iomem on a running target""" def invoke(self, arg, from_tty): return show_lx_resources("iomem_resource") + LxIOMem() @@ -100,6 +103,7 @@ Equivalent to cat /proc/ioports on a running target""" def invoke(self, arg, from_tty): return show_lx_resources("ioport_resource") + LxIOPorts() @@ -149,7 +153,7 @@ values of that process namespace""" if len(argv) >= 1: try: pid = int(argv[0]) - except: + except gdb.error: raise gdb.GdbError("Provide a PID as integer value") else: pid = 1 @@ -195,6 +199,7 @@ values of that process namespace""" info_opts(FS_INFO, s_flags), info_opts(MNT_INFO, m_flags))) + LxMounts() @@ -259,7 +264,7 @@ class LxFdtDump(gdb.Command): try: f = open(filename, 'wb') - except: + except gdb.error: raise gdb.GdbError("Could not open file to dump fdt") f.write(fdt_buf) @@ -267,4 +272,5 @@ class LxFdtDump(gdb.Command): gdb.write("Dumped fdt blob to " + filename + "\n") + LxFdtDump() diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py new file mode 100644 index 000000000000..39db889b874c --- /dev/null +++ b/scripts/gdb/linux/rbtree.py @@ -0,0 +1,177 @@ +# 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/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() diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index f6ab3ccf698f..0301dc1e0138 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -79,6 +79,7 @@ class LxPs(gdb.Command): pid=task["pid"], comm=task["comm"].string())) + LxPs() @@ -134,4 +135,5 @@ variable.""" else: raise gdb.GdbError("No task of PID " + str(pid)) + LxThreadInfoByPidFunc() diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py new file mode 100644 index 000000000000..071d0dd5a634 --- /dev/null +++ b/scripts/gdb/linux/timerlist.py @@ -0,0 +1,219 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2019 Google LLC. + +import binascii +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").get_type() +hrtimer_type = utils.CachedType("struct hrtimer").get_type() + + +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.pointer(), + "node") + timer = utils.container_of(timerqueue, hrtimer_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_64") + 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: + fmts = [(" .{} : {} nsecs", 'expires_next'), + (" .{} : {}", 'hres_active'), + (" .{} : {}", 'nr_events'), + (" .{} : {}", 'nr_retries'), + (" .{} : {}", 'nr_hangs'), + (" .{} : {}", 'max_hang_time')] + text += "\n".join([s.format(f, cpu_base[f]) for s, f in fmts]) + 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]) + text += "\njiffies: {}\n".format(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 + + +def pr_cpumask(mask): + nr_cpu_ids = 1 + if constants.LX_NR_CPUS > 1: + nr_cpu_ids = gdb.parse_and_eval("nr_cpu_ids") + + inf = gdb.inferiors()[0] + bits = mask['bits'] + num_bytes = (nr_cpu_ids + 7) / 8 + buf = utils.read_memoryview(inf, bits, num_bytes).tobytes() + buf = binascii.b2a_hex(buf) + + chunks = [] + i = num_bytes + while i > 0: + i -= 1 + start = i * 2 + end = start + 2 + chunks.append(buf[start:end]) + if i != 0 and i % 4 == 0: + chunks.append(',') + + extra = nr_cpu_ids % 8 + if 0 < extra <= 4: + chunks[0] = chunks[0][0] # Cut off the first 0 + + return "".join(chunks) + + +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") + mask = pr_cpumask(mask) + text += "tick_broadcast_mask: {}\n".format(mask) + if constants.LX_CONFIG_TICK_ONESHOT: + mask = gdb.parse_and_eval("tick_broadcast_oneshot_mask") + mask = pr_cpumask(mask) + text += "tick_broadcast_oneshot_mask: {}\n".format(mask) + text += "\n" + + tick_cpu_devices = gdb.parse_and_eval("&tick_cpu_device") + for cpu in cpus.each_online_cpu(): + tick_dev = cpus.per_cpu(tick_cpu_devices, cpu) + text += print_tickdevice(tick_dev, cpu) + text += "\n" + + gdb.write(text) + + +LxTimerList() diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 50805874cfc3..bc67126118c4 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -66,6 +66,7 @@ Note that TYPE and ELEMENT have to be quoted as strings.""" return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), elementname.string()) + ContainerOf() @@ -148,14 +149,14 @@ def get_gdbserver_type(): def probe_qemu(): try: return gdb.execute("monitor info version", to_string=True) != "" - except: + except gdb.error: return False def probe_kgdb(): try: thread_info = gdb.execute("info thread 2", to_string=True) return "shadowCPU0" in thread_info - except: + except gdb.error: return False global gdbserver_type @@ -172,7 +173,7 @@ def get_gdbserver_type(): def gdb_eval_or_none(expresssion): try: return gdb.parse_and_eval(expresssion) - except: + except gdb.error: return None diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 6e0b0afd888a..eff5a48ac026 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -27,7 +27,11 @@ else: import linux.modules import linux.dmesg import linux.tasks + import linux.config import linux.cpus import linux.lists + import linux.rbtree import linux.proc import linux.constants + import linux.timerlist + import linux.clk |