Blame view

kernel/linux-rt-4.4.41/scripts/gdb/linux/lists.py 2.83 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  #
  # gdb helper commands and functions for Linux kernel debugging
  #
  #  list tools
  #
  # Copyright (c) Thiebaud Weksteen, 2015
  #
  # Authors:
  #  Thiebaud Weksteen <thiebaud@weksteen.fr>
  #
  # This work is licensed under the terms of the GNU GPL version 2.
  #
  
  import gdb
  
  from linux import utils
  
  list_head = utils.CachedType("struct list_head")
  
  
  def list_check(head):
      nb = 0
      if (head.type == list_head.get_type().pointer()):
          head = head.dereference()
      elif (head.type != list_head.get_type()):
          raise gdb.GdbError('argument must be of type (struct list_head [*])')
      c = head
      try:
          gdb.write("Starting with: {}
  ".format(c))
      except gdb.MemoryError:
          gdb.write('head is not accessible
  ')
          return
      while True:
          p = c['prev'].dereference()
          n = c['next'].dereference()
          try:
              if p['next'] != c.address:
                  gdb.write('prev.next != current: '
                            'current@{current_addr}={current} '
                            'prev@{p_addr}={p}
  '.format(
                                current_addr=c.address,
                                current=c,
                                p_addr=p.address,
                                p=p,
                            ))
                  return
          except gdb.MemoryError:
              gdb.write('prev is not accessible: '
                        'current@{current_addr}={current}
  '.format(
                            current_addr=c.address,
                            current=c
                        ))
              return
          try:
              if n['prev'] != c.address:
                  gdb.write('next.prev != current: '
                            'current@{current_addr}={current} '
                            'next@{n_addr}={n}
  '.format(
                                current_addr=c.address,
                                current=c,
                                n_addr=n.address,
                                n=n,
                            ))
                  return
          except gdb.MemoryError:
              gdb.write('next is not accessible: '
                        'current@{current_addr}={current}
  '.format(
                            current_addr=c.address,
                            current=c
                        ))
              return
          c = n
          nb += 1
          if c == head:
              gdb.write("list is consistent: {} node(s)
  ".format(nb))
              return
  
  
  class LxListChk(gdb.Command):
      """Verify a list consistency"""
  
      def __init__(self):
          super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA,
                                          gdb.COMPLETE_EXPRESSION)
  
      def invoke(self, arg, from_tty):
          argv = gdb.string_to_argv(arg)
          if len(argv) != 1:
              raise gdb.GdbError("lx-list-check takes one argument")
          list_check(gdb.parse_and_eval(argv[0]))
  
  LxListChk()