def setup_xen_m2p(cls, symbol: gdb.Symbol) -> None: xen_domain_type = int(symbol.value()) # XXX: this is quite lazy... if xen_domain_type == 0: return cls.machine_to_phys_nr = int(get_symbol_value("machine_to_phys_nr")) cls.xen_max_p2m_pfn = int(get_symbol_value("xen_max_p2m_pfn")) cls.xen_p2m_addr = get_symbol_value("xen_p2m_addr") cls.xen_m2p_needed = True
def print_vmstats(self) -> None: try: vm_stat = get_symbol_value("vm_stat") except MissingSymbolError: raise CommandError("Support for new-style vmstat is unimplemented.") from None print(" VM_STAT:") #TODO put this... where? nr_items = VmStat.nr_stat_items stats = [0] * nr_items for item in range(0, nr_items): # TODO abstract atomic? stats[item] = int(vm_stat[item]["counter"]) diffs = [0] * nr_items for zone in for_each_populated_zone(): zone.add_vmstat_diffs(diffs) self.__print_vmstat(stats, diffs) print() print(" VM_EVENT_STATES:") vm_events = VmStat.get_events() names = VmStat.get_event_names() just = max(map(len, names)) for name, val in zip(names, vm_events): print("%s: %d" % (name.rjust(just), val))
def setup_tasks(self) -> None: """ Populate GDB's thread list using the kernel's task lists This method will iterate over the kernel's task lists, create a LinuxTask object, and create a gdb thread for each one. The threads will be built so that the registers are ready to be populated, which allows symbolic stack traces to be made available. """ from crash.types.percpu import get_percpu_vars from crash.types.task import LinuxTask, for_each_all_tasks import crash.cache.tasks # pylint: disable=redefined-outer-name gdb.execute('set print thread-events 0') rqs = get_percpu_vars(self.symbols.runqueues) rqscurrs = {int(x["curr"]): k for (k, x) in rqs.items()} print("Loading tasks...", end='') sys.stdout.flush() task_count = 0 try: crashing_cpu = int(get_symbol_value('crashing_cpu')) except MissingSymbolError: crashing_cpu = -1 for task in for_each_all_tasks(): ltask = LinuxTask(task) active = int(task.address) in rqscurrs if active: cpu = rqscurrs[int(task.address)] regs = self.vmcore.attr.cpu[cpu].reg ltask.set_active(cpu, regs) ptid = (LINUX_KERNEL_PID, task['pid'], 0) try: thread = gdb.selected_inferior().new_thread(ptid) thread.info = ltask except gdb.error: print("Failed to setup task @{:#x}".format(int(task.address))) continue thread.name = task['comm'].string() if active and cpu == crashing_cpu: self.crashing_thread = thread self.arch.setup_thread_info(thread) ltask.attach_thread(thread) ltask.set_get_stack_pointer(self.arch.get_stack_pointer) crash.cache.tasks.cache_task(ltask) task_count += 1 if task_count % 100 == 0: print(".", end='') sys.stdout.flush() print(" done. ({} tasks total)".format(task_count)) gdb.selected_inferior().executing = False
def extract_vermagic(self) -> str: """ Returns the vermagic from the loaded vmlinux Returns: str: The version text. """ try: magic = get_symbol_value('vermagic') return magic.string() except (AttributeError, NameError): pass return self._get_minsymbol_as_string('vermagic')
def extract_version(self) -> str: """ Returns the version from the loaded vmlinux If debuginfo is available, ``init_uts_ns`` will be used. Otherwise, it will be extracted from the version banner. Returns: str: The version text. """ try: uts = get_symbol_value('init_uts_ns') return uts['name']['release'].string() except (AttributeError, NameError, MissingSymbolError): pass banner = self._get_minsymbol_as_string('linux_banner') return banner.split(' ')[2]
def test_get_symbol_value_good(self): with self.assertRaises(MissingSymbolError): sym = get_symbol_value("test_struct_bad")
def test_get_symbol_value_good(self): sym = get_symbol_value("test_struct") self.assertTrue(isinstance(sym, gdb.Value))
def test_get_symbol_value_good(self): with self.assertRaises(MissingSymbolError): sym = get_symbol_value("test_struct_bad")
def test_get_symbol_value_good(self): sym = get_symbol_value("test_struct") self.assertTrue(isinstance(sym, gdb.Value))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # bsc#1031358 # This script dumps stuck requests for every disk on the system from crash.subsystem.storage import for_each_disk from crash.subsystem.storage.decoders import for_each_bio_in_stack from crash.subsystem.storage import gendisk_name from crash.subsystem.storage.block import for_each_request_in_queue from crash.types.list import list_for_each_entry from crash.util import get_symbol_value from crash.cache.syscache import kernel, jiffies_to_msec empty = [] flush_end_io = get_symbol_value('flush_end_io') for b in for_each_disk(): name = gendisk_name(b) count = 0 for r in for_each_request_in_queue(b['queue']): age_in_jiffies = kernel.jiffies - r['start_time'] age = float(int(kernel.jiffies_to_msec(age_in_jiffies))) / 1000 if count == 0: print name if r['bio']: print "{}: {:x} request: age={}s, bio chain".format( count, int(r.address), age, int(r['bio'])) n = 0 for entry in for_each_bio_in_stack(r['bio']): print " {}: {}".format(n, entry['description'])
def register_journal_buffer_io_sync(cls, sym): # ext3/ext4 and jbd/jbd2 share names but not implementations b = gdb.block_for_pc(long(sym.value().address)) sym = get_symbol_value('journal_end_buffer_io_sync', b) register_buffer_head_decoder(sym, cls.decode_journal_buffer_io_sync)
def register_journal_buffer_io_sync(cls, sym): # ext3/ext4 and jbd/jbd2 share names but not implementations b = gdb.block_for_pc(long(sym.value().address)) sym = get_symbol_value('journal_end_buffer_io_sync', b) register_buffer_head_decoder(sym, cls.decode_journal_buffer_io_sync)