linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@siemens.com>
To: Andrew Morton <akpm@linux-foundation.org>, linux-kernel@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Jason Wessel <jason.wessel@windriver.com>,
	kgdb-bugreport@lists.sourceforge.net,
	Andi Kleen <andi@firstfloor.org>, Tom Tromey <tromey@redhat.com>,
	Ben Widawsky <ben@bwidawsk.net>, Borislav Petkov <bp@suse.de>
Subject: [PATCH v11 05/28] scripts/gdb: Add lx-symbols command
Date: Thu, 29 Jan 2015 07:46:24 +0100	[thread overview]
Message-ID: <0492df685c4802a9c977195196cd3236c3abd3c4.1422514006.git.jan.kiszka@siemens.com> (raw)
In-Reply-To: <cover.1422514006.git.jan.kiszka@siemens.com>
In-Reply-To: <cover.1422514006.git.jan.kiszka@siemens.com>

This is probably the most useful helper when debugging kernel modules:
lx-symbols first reloads vmlinux. Then it searches recursively for *.ko
files in the specified paths and the current directory. Finally it walks
the kernel's module list, issuing the necessary add-symbol-file command
for each loaded module so that gdb knows which module symbol corresponds
to which address. It also looks up variable sections (bss, data, rodata)
and appends their address to the add-symbole-file command line. This
allows to access global module variables just like any other variable.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 scripts/gdb/linux/symbols.py | 127 +++++++++++++++++++++++++++++++++++++++++++
 scripts/gdb/vmlinux-gdb.py   |   1 +
 2 files changed, 128 insertions(+)
 create mode 100644 scripts/gdb/linux/symbols.py

diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
new file mode 100644
index 0000000..bd21a96
--- /dev/null
+++ b/scripts/gdb/linux/symbols.py
@@ -0,0 +1,127 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+#  load kernel and module symbols
+#
+# Copyright (c) Siemens AG, 2011-2013
+#
+# Authors:
+#  Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+import os
+import re
+import string
+
+from linux import modules, utils
+
+
+class LxSymbols(gdb.Command):
+    """(Re-)load symbols of Linux kernel and currently loaded modules.
+
+The kernel (vmlinux) is taken from the current working directly. Modules (.ko)
+are scanned recursively, starting in the same directory. Optionally, the module
+search path can be extended by a space separated list of paths passed to the
+lx-symbols command."""
+
+    module_paths = []
+    module_files = []
+    module_files_updated = False
+
+    def __init__(self):
+        super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES,
+                                        gdb.COMPLETE_FILENAME)
+
+    def _update_module_files(self):
+        self.module_files = []
+        for path in self.module_paths:
+            gdb.write("scanning for modules in {0}\n".format(path))
+            for root, dirs, files in os.walk(path):
+                for name in files:
+                    if name.endswith(".ko"):
+                        self.module_files.append(root + "/" + name)
+        self.module_files_updated = True
+
+    def _get_module_file(self, module_name):
+        module_pattern = ".*/{0}\.ko$".format(
+            string.replace(module_name, "_", r"[_\-]"))
+        for name in self.module_files:
+            if re.match(module_pattern, name) and os.path.exists(name):
+                return name
+        return None
+
+    def _section_arguments(self, module):
+        try:
+            sect_attrs = module['sect_attrs'].dereference()
+        except gdb.error:
+            return ""
+        attrs = sect_attrs['attrs']
+        section_name_to_address = {
+            attrs[n]['name'].string() : attrs[n]['address']
+            for n in range(sect_attrs['nsections'])}
+        args = []
+        for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]:
+            address = section_name_to_address.get(section_name)
+            if address:
+                args.append(" -s {name} {addr}".format(
+                    name=section_name, addr=str(address)))
+        return "".join(args)
+
+    def load_module_symbols(self, module):
+        module_name = module['name'].string()
+        module_addr = str(module['module_core']).split()[0]
+
+        module_file = self._get_module_file(module_name)
+        if not module_file and not self.module_files_updated:
+            self._update_module_files()
+            module_file = self._get_module_file(module_name)
+
+        if module_file:
+            gdb.write("loading @{addr}: {filename}\n".format(
+                addr=module_addr, filename=module_file))
+            cmdline = "add-symbol-file {filename} {addr}{sections}".format(
+                filename=module_file,
+                addr=module_addr,
+                sections=self._section_arguments(module))
+            gdb.execute(cmdline, to_string=True)
+        else:
+            gdb.write("no module object found for '{0}'\n".format(module_name))
+
+    def load_all_symbols(self):
+        gdb.write("loading vmlinux\n")
+
+        # Dropping symbols will disable all breakpoints. So save their states
+        # and restore them afterward.
+        saved_states = []
+        if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None:
+            for bp in gdb.breakpoints():
+                saved_states.append({'breakpoint': bp, 'enabled': bp.enabled})
+
+        # drop all current symbols and reload vmlinux
+        gdb.execute("symbol-file", to_string=True)
+        gdb.execute("symbol-file vmlinux")
+
+        module_list = modules.ModuleList()
+        if not module_list:
+            gdb.write("no modules found\n")
+        else:
+            [self.load_module_symbols(module) for module in module_list]
+
+        for saved_state in saved_states:
+            saved_state['breakpoint'].enabled = saved_state['enabled']
+
+    def invoke(self, arg, from_tty):
+        self.module_paths = arg.split()
+        self.module_paths.append(os.getcwd())
+
+        # enforce update
+        self.module_files = []
+        self.module_files_updated = False
+
+        self.load_all_symbols()
+
+
+LxSymbols()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index 6495841..0b0faa4 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -23,3 +23,4 @@ except:
               "work.\n")
 else:
     import linux.utils
+    import linux.symbols
-- 
2.1.4


  parent reply	other threads:[~2015-01-29  7:21 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-29  6:46 [PATCH v11 00/28] Add gdb python scripts as kernel debugging helpers Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 01/28] scripts/gdb: Add infrastructure Jan Kiszka
2015-01-29 13:23   ` Michal Marek
2015-01-29 13:37     ` Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 02/28] scripts/gdb: Add cache for type objects Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 03/28] scripts/gdb: Add container_of helper and convenience function Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 04/28] scripts/gdb: Add module iteration class Jan Kiszka
2015-01-29  6:46 ` Jan Kiszka [this message]
2015-01-29  6:46 ` [PATCH v11 06/28] module: Do not inline do_init_module Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 07/28] scripts/gdb: Add automatic symbol reloading on module insertion Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 08/28] scripts/gdb: Add internal helper and convenience function to look up a module Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 09/28] scripts/gdb: Add get_target_endianness helper Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 10/28] scripts/gdb: Add read_u16/32/64 helpers Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 11/28] scripts/gdb: Add lx-dmesg command Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 12/28] scripts/gdb: Add task iteration class Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 13/28] scripts/gdb: Add helper and convenience function to look up tasks Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 14/28] scripts/gdb: Add is_target_arch helper Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 15/28] scripts/gdb: Add internal helper and convenience function to retrieve thread_info Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 16/28] scripts/gdb: Add get_gdbserver_type helper Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 17/28] scripts/gdb: Add internal helper and convenience function for per-cpu lookup Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 18/28] scripts/gdb: Add lx_current convenience function Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 19/28] scripts/gdb: Add class to iterate over CPU masks Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 20/28] scripts/gdb: Add lx-lsmod command Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 21/28] scripts/gdb: Add basic documentation Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 22/28] scripts/gdb: Port to python3 / gdb7.7 Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 23/28] scripts/gdb: Ignore byte-compiled python files Jan Kiszka
2015-01-29 13:15   ` Michal Marek
2015-01-29 13:35     ` Jan Kiszka
2015-01-29 14:34       ` Daniel Thompson
2015-01-29 14:41         ` Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 24/28] scripts/gdb: Use a generator instead of iterator for task list Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 25/28] scripts/gdb: Convert ModuleList to generator function Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 26/28] scripts/gdb: Convert CpuList " Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 27/28] scripts/gdb: Define maintainer Jan Kiszka
2015-01-29  6:46 ` [PATCH v11 28/28] scripts/gdb: Disable pagination while printing from breakpoint handler Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0492df685c4802a9c977195196cd3236c3abd3c4.1422514006.git.jan.kiszka@siemens.com \
    --to=jan.kiszka@siemens.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=ben@bwidawsk.net \
    --cc=bp@suse.de \
    --cc=jason.wessel@windriver.com \
    --cc=kgdb-bugreport@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).