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 14import gdb 15 16from linux import utils 17 18list_head = utils.CachedType("struct list_head") 19 20 21def list_check(head): 22 nb = 0 23 if (head.type == list_head.get_type().pointer()): 24 head = head.dereference() 25 elif (head.type != list_head.get_type()): 26 raise gdb.GdbError('argument must be of type (struct list_head [*])') 27 c = head 28 try: 29 gdb.write("Starting with: {}\n".format(c)) 30 except gdb.MemoryError: 31 gdb.write('head is not accessible\n') 32 return 33 while True: 34 p = c['prev'].dereference() 35 n = c['next'].dereference() 36 try: 37 if p['next'] != c.address: 38 gdb.write('prev.next != current: ' 39 'current@{current_addr}={current} ' 40 'prev@{p_addr}={p}\n'.format( 41 current_addr=c.address, 42 current=c, 43 p_addr=p.address, 44 p=p, 45 )) 46 return 47 except gdb.MemoryError: 48 gdb.write('prev is not accessible: ' 49 'current@{current_addr}={current}\n'.format( 50 current_addr=c.address, 51 current=c 52 )) 53 return 54 try: 55 if n['prev'] != c.address: 56 gdb.write('next.prev != current: ' 57 'current@{current_addr}={current} ' 58 'next@{n_addr}={n}\n'.format( 59 current_addr=c.address, 60 current=c, 61 n_addr=n.address, 62 n=n, 63 )) 64 return 65 except gdb.MemoryError: 66 gdb.write('next is not accessible: ' 67 'current@{current_addr}={current}\n'.format( 68 current_addr=c.address, 69 current=c 70 )) 71 return 72 c = n 73 nb += 1 74 if c == head: 75 gdb.write("list is consistent: {} node(s)\n".format(nb)) 76 return 77 78 79class LxListChk(gdb.Command): 80 """Verify a list consistency""" 81 82 def __init__(self): 83 super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA, 84 gdb.COMPLETE_EXPRESSION) 85 86 def invoke(self, arg, from_tty): 87 argv = gdb.string_to_argv(arg) 88 if len(argv) != 1: 89 raise gdb.GdbError("lx-list-check takes one argument") 90 list_check(gdb.parse_and_eval(argv[0])) 91 92LxListChk() 93