gdbmacros.txt 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #
  2. # This file contains a few gdb macros (user defined commands) to extract
  3. # useful information from kernel crashdump (kdump) like stack traces of
  4. # all the processes or a particular process and trapinfo.
  5. #
  6. # These macros can be used by copying this file in .gdbinit (put in home
  7. # directory or current directory) or by invoking gdb command with
  8. # --command=<command-file-name> option
  9. #
  10. # Credits:
  11. # Alexander Nyberg <alexn@telia.com>
  12. # V Srivatsa <vatsa@in.ibm.com>
  13. # Maneesh Soni <maneesh@in.ibm.com>
  14. #
  15. define bttnobp
  16. set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
  17. set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
  18. set $init_t=&init_task
  19. set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
  20. while ($next_t != $init_t)
  21. set $next_t=(struct task_struct *)$next_t
  22. printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  23. printf "===================\n"
  24. set var $stackp = $next_t.thread.esp
  25. set var $stack_top = ($stackp & ~4095) + 4096
  26. while ($stackp < $stack_top)
  27. if (*($stackp) > _stext && *($stackp) < _sinittext)
  28. info symbol *($stackp)
  29. end
  30. set $stackp += 4
  31. end
  32. set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
  33. while ($next_th != $next_t)
  34. set $next_th=(struct task_struct *)$next_th
  35. printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  36. printf "===================\n"
  37. set var $stackp = $next_t.thread.esp
  38. set var $stack_top = ($stackp & ~4095) + 4096
  39. while ($stackp < $stack_top)
  40. if (*($stackp) > _stext && *($stackp) < _sinittext)
  41. info symbol *($stackp)
  42. end
  43. set $stackp += 4
  44. end
  45. set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
  46. end
  47. set $next_t=(char *)($next_t->tasks.next) - $tasks_off
  48. end
  49. end
  50. document bttnobp
  51. dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
  52. end
  53. define btt
  54. set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
  55. set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
  56. set $init_t=&init_task
  57. set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
  58. while ($next_t != $init_t)
  59. set $next_t=(struct task_struct *)$next_t
  60. printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  61. printf "===================\n"
  62. set var $stackp = $next_t.thread.esp
  63. set var $stack_top = ($stackp & ~4095) + 4096
  64. set var $stack_bot = ($stackp & ~4095)
  65. set $stackp = *($stackp)
  66. while (($stackp < $stack_top) && ($stackp > $stack_bot))
  67. set var $addr = *($stackp + 4)
  68. info symbol $addr
  69. set $stackp = *($stackp)
  70. end
  71. set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
  72. while ($next_th != $next_t)
  73. set $next_th=(struct task_struct *)$next_th
  74. printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
  75. printf "===================\n"
  76. set var $stackp = $next_t.thread.esp
  77. set var $stack_top = ($stackp & ~4095) + 4096
  78. set var $stack_bot = ($stackp & ~4095)
  79. set $stackp = *($stackp)
  80. while (($stackp < $stack_top) && ($stackp > $stack_bot))
  81. set var $addr = *($stackp + 4)
  82. info symbol $addr
  83. set $stackp = *($stackp)
  84. end
  85. set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
  86. end
  87. set $next_t=(char *)($next_t->tasks.next) - $tasks_off
  88. end
  89. end
  90. document btt
  91. dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
  92. end
  93. define btpid
  94. set var $pid = $arg0
  95. set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
  96. set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
  97. set $init_t=&init_task
  98. set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
  99. set var $pid_task = 0
  100. while ($next_t != $init_t)
  101. set $next_t=(struct task_struct *)$next_t
  102. if ($next_t.pid == $pid)
  103. set $pid_task = $next_t
  104. end
  105. set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
  106. while ($next_th != $next_t)
  107. set $next_th=(struct task_struct *)$next_th
  108. if ($next_th.pid == $pid)
  109. set $pid_task = $next_th
  110. end
  111. set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
  112. end
  113. set $next_t=(char *)($next_t->tasks.next) - $tasks_off
  114. end
  115. printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
  116. printf "===================\n"
  117. set var $stackp = $pid_task.thread.esp
  118. set var $stack_top = ($stackp & ~4095) + 4096
  119. set var $stack_bot = ($stackp & ~4095)
  120. set $stackp = *($stackp)
  121. while (($stackp < $stack_top) && ($stackp > $stack_bot))
  122. set var $addr = *($stackp + 4)
  123. info symbol $addr
  124. set $stackp = *($stackp)
  125. end
  126. end
  127. document btpid
  128. backtrace of pid
  129. end
  130. define trapinfo
  131. set var $pid = $arg0
  132. set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
  133. set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
  134. set $init_t=&init_task
  135. set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
  136. set var $pid_task = 0
  137. while ($next_t != $init_t)
  138. set $next_t=(struct task_struct *)$next_t
  139. if ($next_t.pid == $pid)
  140. set $pid_task = $next_t
  141. end
  142. set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
  143. while ($next_th != $next_t)
  144. set $next_th=(struct task_struct *)$next_th
  145. if ($next_th.pid == $pid)
  146. set $pid_task = $next_th
  147. end
  148. set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
  149. end
  150. set $next_t=(char *)($next_t->tasks.next) - $tasks_off
  151. end
  152. printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
  153. $pid_task.thread.cr2, $pid_task.thread.error_code
  154. end
  155. document trapinfo
  156. Run info threads and lookup pid of thread #1
  157. 'trapinfo <pid>' will tell you by which trap & possibly
  158. address the kernel panicked.
  159. end
  160. define dmesg
  161. set $i = 0
  162. set $end_idx = (log_end - 1) & (log_buf_len - 1)
  163. while ($i < logged_chars)
  164. set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1)
  165. if ($idx + 100 <= $end_idx) || \
  166. ($end_idx <= $idx && $idx + 100 < log_buf_len)
  167. printf "%.100s", &log_buf[$idx]
  168. set $i = $i + 100
  169. else
  170. printf "%c", log_buf[$idx]
  171. set $i = $i + 1
  172. end
  173. end
  174. end
  175. document dmesg
  176. print the kernel ring buffer
  177. end