From 850202e17df68c51593bab36a26c8d9279f8c029 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 17 Feb 2015 13:46:44 -0800 Subject: scripts/gdb: add module iteration class Will soon be used for loading symbols, printing global variables or listing modules. Signed-off-by: Jan Kiszka Cc: Thomas Gleixner Cc: Jason Wessel Cc: Andi Kleen Cc: Ben Widawsky Cc: Borislav Petkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/modules.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/gdb/linux/modules.py (limited to 'scripts/gdb/linux/modules.py') diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py new file mode 100644 index 000000000000..8a65c3d5eecb --- /dev/null +++ b/scripts/gdb/linux/modules.py @@ -0,0 +1,39 @@ +# +# gdb helper commands and functions for Linux kernel debugging +# +# module tools +# +# Copyright (c) Siemens AG, 2013 +# +# Authors: +# Jan Kiszka +# +# This work is licensed under the terms of the GNU GPL version 2. +# + +import gdb + +from linux import utils + + +module_type = utils.CachedType("struct module") + + +class ModuleList: + def __init__(self): + global module_type + self.module_ptr_type = module_type.get_type().pointer() + modules = gdb.parse_and_eval("modules") + self.curr_entry = modules['next'] + self.end_of_list = modules.address + + def __iter__(self): + return self + + def next(self): + entry = self.curr_entry + if entry != self.end_of_list: + self.curr_entry = entry['next'] + return utils.container_of(entry, self.module_ptr_type, "list") + else: + raise StopIteration -- cgit v1.2.2 From 7b599ef535a7faef53034fb7fb150b61057efe28 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 17 Feb 2015 13:46:55 -0800 Subject: scripts/gdb: add internal helper and convenience function to look up a module Add the internal helper get_module_by_name to obtain the module structure corresponding to the given name. Also export this service as a convenience function. Signed-off-by: Jan Kiszka Cc: Thomas Gleixner Cc: Jason Wessel Cc: Andi Kleen Cc: Ben Widawsky Cc: Borislav Petkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/modules.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'scripts/gdb/linux/modules.py') diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index 8a65c3d5eecb..531f7632d03f 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -37,3 +37,31 @@ class ModuleList: return utils.container_of(entry, self.module_ptr_type, "list") else: raise StopIteration + + +def find_module_by_name(name): + for module in ModuleList(): + if module['name'].string() == name: + return module + return None + + +class LxModule(gdb.Function): + """Find module by name and return the module variable. + +$lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules +of the target and return that module variable which MODULE matches.""" + + def __init__(self): + super(LxModule, self).__init__("lx_module") + + def invoke(self, mod_name): + mod_name = mod_name.string() + module = find_module_by_name(mod_name) + if module: + return module.dereference() + else: + raise gdb.GdbError("Unable to find MODULE " + mod_name) + + +LxModule() -- cgit v1.2.2 From 5403727f985ba39967c899a56fff5bbd2c9a9f36 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 17 Feb 2015 13:47:29 -0800 Subject: scripts/gdb: add lx-lsmod command This adds a lsmod-like command to list all currently loaded modules of the target. Signed-off-by: Jan Kiszka Cc: Thomas Gleixner Cc: Jason Wessel Cc: Andi Kleen Cc: Ben Widawsky Cc: Borislav Petkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/modules.py | 46 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'scripts/gdb/linux/modules.py') diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index 531f7632d03f..e7c99e9c9620 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -13,7 +13,7 @@ import gdb -from linux import utils +from linux import cpus, utils module_type = utils.CachedType("struct module") @@ -65,3 +65,47 @@ of the target and return that module variable which MODULE matches.""" LxModule() + + +class LxLsmod(gdb.Command): + """List currently loaded modules.""" + + _module_use_type = utils.CachedType("struct module_use") + + def __init__(self): + super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + gdb.write( + "Address{0} Module Size Used by\n".format( + " " if utils.get_long_type().sizeof == 8 else "")) + + for module in ModuleList(): + ref = 0 + module_refptr = module['refptr'] + for cpu in cpus.CpuList("cpu_possible_mask"): + refptr = cpus.per_cpu(module_refptr, cpu) + ref += refptr['incs'] + ref -= refptr['decs'] + + gdb.write("{address} {name:<19} {size:>8} {ref}".format( + address=str(module['module_core']).split()[0], + name=module['name'].string(), + size=module['core_size'], + ref=ref)) + + source_list = module['source_list'] + t = self._module_use_type.get_type().pointer() + entry = source_list['next'] + first = True + while entry != source_list.address: + use = utils.container_of(entry, t, "source_list") + gdb.write("{separator}{name}".format( + separator=" " if first else ",", + name=use['source']['name'].string())) + first = False + entry = entry['next'] + gdb.write("\n") + + +LxLsmod() -- cgit v1.2.2 From 276d97d90a2485f9a830a7a8242e4317b24c896f Mon Sep 17 00:00:00 2001 From: Pantelis Koukousoulas Date: Tue, 17 Feb 2015 13:47:35 -0800 Subject: scripts/gdb: port to python3 / gdb7.7 I tried to use these scripts in an ubuntu 14.04 host (gdb 7.7 compiled against python 3.3) but there were several errors. I believe this patch fixes these issues so that the commands now work (I tested lx-symbols, lx-dmesg, lx-lsmod). Main issues that needed to be resolved: * In python 2 iterators have a "next()" method. In python 3 it is __next__() instead (so let's just add both). * In older python versions there was an implicit conversion in object.__format__() (used when an object is in string.format()) where it was converting the object to str first and then calling str's __format__(). This has now been removed so we must explicitly convert to str the objects for which we need to keep this behavior. * In dmesg.py: in python 3 log_buf is now a "memoryview" object which needs to be converted to a string in order to use string methods like "splitlines()". Luckily memoryview exists in python 2.7.6 as well, so we can convert log_buf to memoryview and use the same code in both python 2 and python 3. This version of the patch has now been tested with gdb 7.7 and both python 3.4 and python 2.7.6 (I think asking for at least python 2.7.6 is a reasonable requirement instead of complicating the code with version checks etc). Signed-off-by: Pantelis Koukousoulas Signed-off-by: Jan Kiszka Cc: Thomas Gleixner Cc: Jason Wessel Cc: Andi Kleen Cc: Ben Widawsky Cc: Borislav Petkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/modules.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'scripts/gdb/linux/modules.py') diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index e7c99e9c9620..2dbf6796ce4f 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -30,7 +30,7 @@ class ModuleList: def __iter__(self): return self - def next(self): + def __next__(self): entry = self.curr_entry if entry != self.end_of_list: self.curr_entry = entry['next'] @@ -38,6 +38,9 @@ class ModuleList: else: raise StopIteration + def next(self): + return self.__next__() + def find_module_by_name(name): for module in ModuleList(): @@ -91,8 +94,8 @@ class LxLsmod(gdb.Command): gdb.write("{address} {name:<19} {size:>8} {ref}".format( address=str(module['module_core']).split()[0], name=module['name'].string(), - size=module['core_size'], - ref=ref)) + size=str(module['core_size']), + ref=str(ref))) source_list = module['source_list'] t = self._module_use_type.get_type().pointer() -- cgit v1.2.2 From fffb944c4e6d3882a7a15c494bd4cde36c68c39c Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 17 Feb 2015 13:47:44 -0800 Subject: scripts/gdb: convert ModuleList to generator function Analogously to the task list, convert the module list to a generator function. It noticeably simplifies the code. Signed-off-by: Jan Kiszka Cc: Thomas Gleixner Cc: Jason Wessel Cc: Andi Kleen Cc: Ben Widawsky Cc: Borislav Petkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/modules.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'scripts/gdb/linux/modules.py') diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index 2dbf6796ce4f..6d497229d026 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -19,31 +19,20 @@ from linux import cpus, utils module_type = utils.CachedType("struct module") -class ModuleList: - def __init__(self): - global module_type - self.module_ptr_type = module_type.get_type().pointer() - modules = gdb.parse_and_eval("modules") - self.curr_entry = modules['next'] - self.end_of_list = modules.address - - def __iter__(self): - return self - - def __next__(self): - entry = self.curr_entry - if entry != self.end_of_list: - self.curr_entry = entry['next'] - return utils.container_of(entry, self.module_ptr_type, "list") - else: - raise StopIteration +def module_list(): + global module_type + module_ptr_type = module_type.get_type().pointer() + modules = gdb.parse_and_eval("modules") + entry = modules['next'] + end_of_list = modules.address - def next(self): - return self.__next__() + while entry != end_of_list: + yield utils.container_of(entry, module_ptr_type, "list") + entry = entry['next'] def find_module_by_name(name): - for module in ModuleList(): + for module in module_list(): if module['name'].string() == name: return module return None @@ -83,7 +72,7 @@ class LxLsmod(gdb.Command): "Address{0} Module Size Used by\n".format( " " if utils.get_long_type().sizeof == 8 else "")) - for module in ModuleList(): + for module in module_list(): ref = 0 module_refptr = module['refptr'] for cpu in cpus.CpuList("cpu_possible_mask"): -- cgit v1.2.2 From a77e15e8b4ccaf43b3a527cbb882bf816c5a629d Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 17 Feb 2015 13:47:47 -0800 Subject: scripts/gdb: convert CpuList to generator function Yet another code simplification. Signed-off-by: Jan Kiszka Cc: Thomas Gleixner Cc: Jason Wessel Cc: Andi Kleen Cc: Ben Widawsky Cc: Borislav Petkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/gdb/linux/modules.py') diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index 6d497229d026..a1504c4f1900 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -75,7 +75,7 @@ class LxLsmod(gdb.Command): for module in module_list(): ref = 0 module_refptr = module['refptr'] - for cpu in cpus.CpuList("cpu_possible_mask"): + for cpu in cpus.cpu_list("cpu_possible_mask"): refptr = cpus.per_cpu(module_refptr, cpu) ref += refptr['incs'] ref -= refptr['decs'] -- cgit v1.2.2