lists.py 2.7 KB

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