Source code for crash.types.klist

# -*- coding: utf-8 -*-
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

from typing import Iterable

from crash.util import container_of
from crash.types.list import list_for_each_entry
from crash.exceptions import CorruptedError, InvalidArgumentError
from crash.util.symbols import Types

import gdb

types = Types(['struct klist_node', 'struct klist'])

[docs]class KlistCorruptedError(CorruptedError): pass
[docs]def klist_for_each(klist: gdb.Value) -> Iterable[gdb.Value]: """ Iterate over a klist and yield each node Args: klist: The list to iterate. The value must be of type ``struct klist`` or ``struct klist *``. Yields: :obj:`gdb.Value`: The next node in the list. The value is of type ``struct klist_node``. """ if klist.type == types.klist_type.pointer(): klist = klist.dereference() elif klist.type != types.klist_type: raise InvalidArgumentError("klist must be gdb.Value representing 'struct klist' or 'struct klist *' not {}" .format(klist.type)) if klist.type is not types.klist_type: types.override('struct klist', klist.type) for node in list_for_each_entry(klist['k_list'], types.klist_node_type, 'n_node'): if node['n_klist'] != klist.address: raise KlistCorruptedError("Corrupted") yield node
[docs]def klist_for_each_entry(klist: gdb.Value, gdbtype: gdb.Type, member: str) -> Iterable[gdb.Value]: """ Iterate over a klist and yield each node's containing object Args: klist: The list to iterate. The value must be of type ``struct klist`` or ``struct klist *``. gdbtype: The type of the containing object member: The name of the member in the containing object that corresponds to the klist_node Yields: :obj:`gdb.Value`: The next node in the list. The value is of the specified type. """ for node in klist_for_each(klist): if node.type is not types.klist_node_type: types.override('struct klist_node', node.type) yield container_of(node, gdbtype, member)