mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-03 17:40:04 +00:00
![Kuan-Ying Lee](/assets/img/avatar_default.png)
When we get an text address from coredump and we cannot find this address in vmlinux, it might located in kernel module. We want to know which kernel module it located in. This GDB scripts can help us to find the target kernel module. (gdb) lx-getmod-by-textaddr 0xffff800002d305ac 0xffff800002d305ac is in kasan_test.ko Link: https://lkml.kernel.org/r/20230808083020.22254-3-Kuan-Ying.Lee@mediatek.com Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee@mediatek.com> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Cc: Chinwen Chang <chinwen.chang@mediatek.com> Cc: Matthias Brugger <matthias.bgg@gmail.com> Cc: Qun-Wei Lin <qun-wei.lin@mediatek.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
131 lines
3.8 KiB
Python
131 lines
3.8 KiB
Python
#
|
|
# gdb helper commands and functions for Linux kernel debugging
|
|
#
|
|
# module tools
|
|
#
|
|
# Copyright (c) Siemens AG, 2013
|
|
#
|
|
# Authors:
|
|
# Jan Kiszka <jan.kiszka@siemens.com>
|
|
#
|
|
# This work is licensed under the terms of the GNU GPL version 2.
|
|
#
|
|
|
|
import gdb
|
|
|
|
from linux import cpus, utils, lists, constants
|
|
|
|
|
|
module_type = utils.CachedType("struct module")
|
|
|
|
|
|
def module_list():
|
|
global module_type
|
|
modules = utils.gdb_eval_or_none("modules")
|
|
if modules is None:
|
|
return
|
|
|
|
module_ptr_type = module_type.get_type().pointer()
|
|
|
|
for module in lists.list_for_each_entry(modules, module_ptr_type, "list"):
|
|
yield module
|
|
|
|
|
|
def find_module_by_name(name):
|
|
for module in module_list():
|
|
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()
|
|
|
|
|
|
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 module_list():
|
|
text = module['mem'][constants.LX_MOD_TEXT]
|
|
text_addr = str(text['base']).split()[0]
|
|
total_size = 0
|
|
|
|
for i in range(constants.LX_MOD_TEXT, constants.LX_MOD_RO_AFTER_INIT + 1):
|
|
total_size += module['mem'][i]['size']
|
|
|
|
gdb.write("{address} {name:<19} {size:>8} {ref}".format(
|
|
address=text_addr,
|
|
name=module['name'].string(),
|
|
size=str(total_size),
|
|
ref=str(module['refcnt']['counter'] - 1)))
|
|
|
|
t = self._module_use_type.get_type().pointer()
|
|
first = True
|
|
sources = module['source_list']
|
|
for use in lists.list_for_each_entry(sources, t, "source_list"):
|
|
gdb.write("{separator}{name}".format(
|
|
separator=" " if first else ",",
|
|
name=use['source']['name'].string()))
|
|
first = False
|
|
|
|
gdb.write("\n")
|
|
|
|
LxLsmod()
|
|
|
|
def help():
|
|
t = """Usage: lx-getmod-by-textaddr [Heximal Address]
|
|
Example: lx-getmod-by-textaddr 0xffff800002d305ac\n"""
|
|
gdb.write("Unrecognized command\n")
|
|
raise gdb.GdbError(t)
|
|
|
|
class LxFindTextAddrinMod(gdb.Command):
|
|
'''Look up loaded kernel module by text address.'''
|
|
|
|
def __init__(self):
|
|
super(LxFindTextAddrinMod, self).__init__('lx-getmod-by-textaddr', gdb.COMMAND_SUPPORT)
|
|
|
|
def invoke(self, arg, from_tty):
|
|
args = gdb.string_to_argv(arg)
|
|
|
|
if len(args) != 1:
|
|
help()
|
|
|
|
addr = gdb.Value(int(args[0], 16)).cast(utils.get_ulong_type())
|
|
for mod in module_list():
|
|
mod_text_start = mod['mem'][constants.LX_MOD_TEXT]['base']
|
|
mod_text_end = mod_text_start + mod['mem'][constants.LX_MOD_TEXT]['size'].cast(utils.get_ulong_type())
|
|
|
|
if addr >= mod_text_start and addr < mod_text_end:
|
|
s = "0x%x" % addr + " is in " + mod['name'].string() + ".ko\n"
|
|
gdb.write(s)
|
|
return
|
|
gdb.write("0x%x is not in any module text section\n" % addr)
|
|
|
|
LxFindTextAddrinMod()
|