~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gdb/linux/lists.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #
  2 # gdb helper commands and functions for Linux kernel debugging
  3 #
  4 #  list tools
  5 #
  6 # Copyright (c) Thiebaud Weksteen, 2015
  7 #
  8 # Authors:
  9 #  Thiebaud Weksteen <thiebaud@weksteen.fr>
 10 #
 11 # This work is licensed under the terms of the GNU GPL version 2.
 12 #
 13 
 14 import gdb
 15 
 16 from linux import utils
 17 
 18 list_head = utils.CachedType("struct list_head")
 19 hlist_head = utils.CachedType("struct hlist_head")
 20 hlist_node = utils.CachedType("struct hlist_node")
 21 
 22 
 23 def list_for_each(head):
 24     if head.type == list_head.get_type().pointer():
 25         head = head.dereference()
 26     elif head.type != list_head.get_type():
 27         raise TypeError("Must be struct list_head not {}"
 28                            .format(head.type))
 29 
 30     if head['next'] == 0:
 31         gdb.write("list_for_each: Uninitialized list '{}' treated as empty\n"
 32                      .format(head.address))
 33         return
 34 
 35     node = head['next'].dereference()
 36     while node.address != head.address:
 37         yield node.address
 38         node = node['next'].dereference()
 39 
 40 
 41 def list_for_each_entry(head, gdbtype, member):
 42     for node in list_for_each(head):
 43         yield utils.container_of(node, gdbtype, member)
 44 
 45 
 46 def hlist_for_each(head):
 47     if head.type == hlist_head.get_type().pointer():
 48         head = head.dereference()
 49     elif head.type != hlist_head.get_type():
 50         raise TypeError("Must be struct hlist_head not {}"
 51                            .format(head.type))
 52 
 53     node = head['first'].dereference()
 54     while node.address:
 55         yield node.address
 56         node = node['next'].dereference()
 57 
 58 
 59 def hlist_for_each_entry(head, gdbtype, member):
 60     for node in hlist_for_each(head):
 61         yield utils.container_of(node, gdbtype, member)
 62 
 63 
 64 def list_check(head):
 65     nb = 0
 66     if (head.type == list_head.get_type().pointer()):
 67         head = head.dereference()
 68     elif (head.type != list_head.get_type()):
 69         raise gdb.GdbError('argument must be of type (struct list_head [*])')
 70     c = head
 71     try:
 72         gdb.write("Starting with: {}\n".format(c))
 73     except gdb.MemoryError:
 74         gdb.write('head is not accessible\n')
 75         return
 76     while True:
 77         p = c['prev'].dereference()
 78         n = c['next'].dereference()
 79         try:
 80             if p['next'] != c.address:
 81                 gdb.write('prev.next != current: '
 82                           'current@{current_addr}={current} '
 83                           'prev@{p_addr}={p}\n'.format(
 84                               current_addr=c.address,
 85                               current=c,
 86                               p_addr=p.address,
 87                               p=p,
 88                           ))
 89                 return
 90         except gdb.MemoryError:
 91             gdb.write('prev is not accessible: '
 92                       'current@{current_addr}={current}\n'.format(
 93                           current_addr=c.address,
 94                           current=c
 95                       ))
 96             return
 97         try:
 98             if n['prev'] != c.address:
 99                 gdb.write('next.prev != current: '
100                           'current@{current_addr}={current} '
101                           'next@{n_addr}={n}\n'.format(
102                               current_addr=c.address,
103                               current=c,
104                               n_addr=n.address,
105                               n=n,
106                           ))
107                 return
108         except gdb.MemoryError:
109             gdb.write('next is not accessible: '
110                       'current@{current_addr}={current}\n'.format(
111                           current_addr=c.address,
112                           current=c
113                       ))
114             return
115         c = n
116         nb += 1
117         if c == head:
118             gdb.write("list is consistent: {} node(s)\n".format(nb))
119             return
120 
121 
122 class LxListChk(gdb.Command):
123     """Verify a list consistency"""
124 
125     def __init__(self):
126         super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA,
127                                         gdb.COMPLETE_EXPRESSION)
128 
129     def invoke(self, arg, from_tty):
130         argv = gdb.string_to_argv(arg)
131         if len(argv) != 1:
132             raise gdb.GdbError("lx-list-check takes one argument")
133         list_check(gdb.parse_and_eval(argv[0]))
134 
135 
136 LxListChk()

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php