Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions crash/cache/modules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

from __future__ import print_function
import os
import gdb
import sys
from crash.cache import CrashCache
from crash.types.list import list_for_each_entry

if sys.version_info.major >= 3:
long = int

class Kmod():
def __init__(self, obj):
self.name = obj['name'].string()
self.objfile = None
self._module = obj

def get_base_addr(self):
return long(self._module.address)

def get_size(self):
return long(self._module['core_size'])

def load_objfile(self, path):
self.objfile = os.path.abspath(path)
try:
gdb.execute("add-symbol-file {} {}".format(path, self._module['module_core']))
except gdb.error:
self.objfile = None
print("Error adding symbol informatation")

class KmodCache(CrashCache):
def __init__(self):
super(KmodCache, self).__init__()
self._modules = {}
self._cache_init = False

def init_modules_cache(self):
if self._cache_init: return

module_type = gdb.lookup_type('struct module')
modules = gdb.lookup_symbol('modules', None)[0].value()
for module in list_for_each_entry(modules, module_type, 'list'):
kmod = Kmod(module)
self._modules[kmod.name] = kmod

self._cache_init = True

def __len__(self):
return len(self._modules)

def __getitem__(self, key):
return self._modules[key]

def __contains__(self, item):
return item in self._modules

def __iter__(self):
return self._modules.__iter__()

def values(self):
return self._modules.values()

cache = KmodCache()


60 changes: 60 additions & 0 deletions crash/commands/pymod.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

from __future__ import print_function

import gdb
import argparse
import sys
from crash.types.list import list_for_each_entry
from crash.commands import CrashCommand
from crash.cache import modules

if sys.version_info.major >= 3:
long = int

class ModCommand(CrashCommand):
"""
"""
def __init__(self, name):
#init parser
parser = argparse.ArgumentParser(prog=name)
group = parser.add_mutually_exclusive_group()
group.add_argument("-s", metavar="module")
parser.add_argument('args', nargs='*')
#initialize module cache

CrashCommand.__init__(self, "mod", parser)

def _list_modules(self):
modules_sorted = []
sort_by_addr = lambda x: long(x.get_base_addr())

print("{0:^16} {1:<16} {2:<8} OBJECT FILE".format("MODULE", "NAME", "SIZE"))

for module in sorted(modules.cache.values(), key=sort_by_addr):
objfile = module.objfile
if objfile is None:
objfile = "(not loaded)"
print("{0:^16x} {1:<16} {2:<8} {3}".format(long(module.get_base_addr()), module.name, module.get_size(), objfile))

def _add_objfile(self, module_name, objfile_path):
#Add handling for not loaded module, results in KeyError
kmod = modules.cache[module_name]
kmod.load_objfile(objfile_path)

def execute(self, argv):
modules.cache.init_modules_cache()
if argv.s is not None:
module_name = argv.s
if len(argv.args):
objfile = argv.args[0]
self._add_objfile(module_name, objfile)
else:
#TODO: Automatically search for the module, perhaps
#merge the stuff from contrib/mod.py
pass
else:
self._list_modules()

ModCommand("mod")