This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[FYI] Python-based symbol loader for Linux kernel inferiors


Hi,

find below my first version of a tiny helper for debugging Linux kernel
modules. If you source this in or stuff it into your .gdbinit, the new
command 'linux-symbols' will be available. Note that it requires
gdb.parse_and_eval support from Tom's python branch.

The linux-symbols command assumes to find vmlinux in the current working
directory, expects to be attached to a running Linux kernel (tested
against qemu, should work with kgdb too), and then loads all required
symbol files to debug both the kernel as well as all currently loaded
modules. It searches for corresponding modules in the working directory
or, optionally, in all paths provided as command arguments.

There is likely still a lot to improve and beautify (does someone know
how to switch of the add-symbol-file output?), but this should improve
module debugging a lot already. And IMHO, it's another nice demo for the
power of the new Python interface.

Jan

---

python
import string
import os
import re

def offset_of(type, field):
	return gdb.parse_and_eval('(unsigned long)&( (' + str(type) + ' *)0)->' + str(field))

def container_of(ptr, type, member):
	return gdb.parse_and_eval('(' + str(type) + ' *)( (unsigned long)' + \
				  str(ptr) + ' - ' + str(offset_of(type, member)) + ')')

class LinuxSymbols (gdb.Command):
	"""(Re-)load symbols of Linux kernel and currently loaded modules."""

	def __init__(self):
		super(LinuxSymbols, self).__init__("linux-symbols", gdb.COMMAND_FILES, gdb.COMPLETE_FILENAME)

	def invoke(self, arg, from_tty):
		print 'loading vmlinux'
		gdb.execute('symbol-file')
		gdb.execute('file vmlinux')

		module_files = []
		paths = arg.split()
		paths.append(os.getcwd())
		for path in paths:
			print 'scanning for modules in ' + path
			for root, dirs, files in os.walk(path):
				for name in files:
					if re.match(r'.*\.ko$', name):
						module_files.append(root + '/' + name)

		modules = gdb.selected_frame().read_var('modules')
		entry = modules['next']
		while entry != modules.address:
			module = container_of(entry, 'struct module', 'list')
			module_name = module['name'].string()
			module_addr = str(module['module_core'])
			module_pattern = '.*/' + string.replace(module_name, '_', r'[_\-]') + r'\.ko$'
			module_path = ''
			for name in module_files:
				if re.match(module_pattern, name):
					module_path = name
					break

			if module_path:
				gdb.execute('add-symbol-file ' + module_path + ' ' + module_addr)
			else:
				print "no module object found for '" + module_name + "'"

			entry = entry['next']

LinuxSymbols()

end

Attachment: signature.asc
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]