gdbinit 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. # Copyright 2014 the V8 project authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. # Print tagged object.
  5. define job
  6. call (void) _v8_internal_Print_Object((void*)($arg0))
  7. end
  8. document job
  9. Print a v8 JavaScript object
  10. Usage: job tagged_ptr
  11. end
  12. # Print content of v8::internal::Handle.
  13. define jh
  14. call (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).location_))
  15. end
  16. document jh
  17. Print content of a v8::internal::Handle
  18. Usage: jh internal_handle
  19. end
  20. # Print content of v8::Local handle.
  21. define jlh
  22. call (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).val_))
  23. end
  24. document jlh
  25. Print content of a v8::Local handle
  26. Usage: jlh local_handle
  27. end
  28. # Print Code objects containing given PC.
  29. define jco
  30. if $argc == 0
  31. call (void) _v8_internal_Print_Code((void*)($pc))
  32. else
  33. call (void) _v8_internal_Print_Code((void*)($arg0))
  34. end
  35. end
  36. document jco
  37. Print a v8 Code object from an internal code address
  38. Usage: jco pc
  39. end
  40. # Print TransitionTree.
  41. define jtt
  42. call (void) _v8_internal_Print_TransitionTree((void*)($arg0))
  43. end
  44. document jtt
  45. Print the complete transition tree of the given v8 Map.
  46. Usage: jtt tagged_ptr
  47. end
  48. # Print JavaScript stack trace.
  49. define jst
  50. call (void) _v8_internal_Print_StackTrace()
  51. end
  52. document jst
  53. Print the current JavaScript stack trace
  54. Usage: jst
  55. end
  56. # Print TurboFan graph node.
  57. define pn
  58. call _v8_internal_Node_Print((void*)($arg0))
  59. end
  60. document pn
  61. Print a v8 TurboFan graph node
  62. Usage: pn node_address
  63. end
  64. # Skip the JavaScript stack.
  65. define jss
  66. set $js_entry_sp=v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_
  67. set $rbp=*(void**)$js_entry_sp
  68. set $rsp=$js_entry_sp + 2*sizeof(void*)
  69. set $pc=*(void**)($js_entry_sp+sizeof(void*))
  70. end
  71. document jss
  72. Skip the jitted stack on x64 to where we entered JS last.
  73. Usage: jss
  74. end
  75. # Execute a simulator command.
  76. python
  77. import gdb
  78. class SimCommand(gdb.Command):
  79. """Sim the current program."""
  80. def __init__ (self):
  81. super (SimCommand, self).__init__ ("sim", gdb.COMMAND_SUPPORT)
  82. def invoke (self, arg, from_tty):
  83. arg_c_string = gdb.Value(arg)
  84. cmd_func = gdb.selected_frame().read_var("_v8_internal_Simulator_ExecDebugCommand")
  85. cmd_func(arg_c_string)
  86. SimCommand()
  87. end
  88. # Print stack trace with assertion scopes.
  89. define bta
  90. python
  91. import re
  92. frame_re = re.compile("^#(\d+)\s*(?:0x[a-f\d]+ in )?(.+) \(.+ at (.+)")
  93. assert_re = re.compile("^\s*(\S+) = .+<v8::internal::Per\w+AssertScope<v8::internal::(\S*), (false|true)>")
  94. btl = gdb.execute("backtrace full", to_string = True).splitlines()
  95. for l in btl:
  96. match = frame_re.match(l)
  97. if match:
  98. print("[%-2s] %-60s %-40s" % (match.group(1), match.group(2), match.group(3)))
  99. match = assert_re.match(l)
  100. if match:
  101. if match.group(3) == "false":
  102. prefix = "Disallow"
  103. color = "\033[91m"
  104. else:
  105. prefix = "Allow"
  106. color = "\033[92m"
  107. print("%s -> %s %s (%s)\033[0m" % (color, prefix, match.group(2), match.group(1)))
  108. end
  109. end
  110. document bta
  111. Print stack trace with assertion scopes
  112. Usage: bta
  113. end
  114. # Search for a pointer inside all valid pages.
  115. define space_find
  116. set $space = $arg0
  117. set $current_page = $space->first_page()
  118. while ($current_page != 0)
  119. printf "# Searching in %p - %p\n", $current_page->area_start(), $current_page->area_end()-1
  120. find $current_page->area_start(), $current_page->area_end()-1, $arg1
  121. set $current_page = $current_page->next_page()
  122. end
  123. end
  124. define heap_find
  125. set $heap = v8::internal::Isolate::Current()->heap()
  126. printf "# Searching for %p in old_space ===============================\n", $arg0
  127. space_find $heap->old_space() ($arg0)
  128. printf "# Searching for %p in map_space ===============================\n", $arg0
  129. space_find $heap->map_space() $arg0
  130. printf "# Searching for %p in code_space ===============================\n", $arg0
  131. space_find $heap->code_space() $arg0
  132. end
  133. document heap_find
  134. Find the location of a given address in V8 pages.
  135. Usage: heap_find address
  136. end
  137. # The 'disassembly-flavor' command is only available on i386 and x84_64.
  138. python
  139. try:
  140. gdb.execute("set disassembly-flavor intel")
  141. except gdb.error:
  142. pass
  143. end
  144. set disable-randomization off
  145. # Install a handler whenever the debugger stops due to a signal. It walks up the
  146. # stack looking for V8_Dcheck / V8_Fatal / OS::DebugBreak frame and moves the
  147. # frame to the one above it so it's immediately at the line of code that
  148. # triggered the stop condition.
  149. python
  150. def v8_stop_handler(event):
  151. frame = gdb.selected_frame()
  152. select_frame = None
  153. message = None
  154. count = 0
  155. # Limit stack scanning since the frames we look for are near the top anyway,
  156. # and otherwise stack overflows can be very slow.
  157. while frame is not None and count < 7:
  158. count += 1
  159. # If we are in a frame created by gdb (e.g. for `(gdb) call foo()`), gdb
  160. # emits a dummy frame between its stack and the program's stack. Abort the
  161. # walk if we see this frame.
  162. if frame.type() == gdb.DUMMY_FRAME: break
  163. if frame.name() == 'V8_Dcheck':
  164. frame_message = gdb.lookup_symbol('message', frame.block())[0]
  165. if frame_message:
  166. message = frame_message.value(frame).string()
  167. select_frame = frame.older()
  168. break
  169. if frame.name() is not None and frame.name().startswith('V8_Fatal'):
  170. select_frame = frame.older()
  171. if frame.name() == 'v8::base::OS::DebugBreak':
  172. select_frame = frame.older()
  173. frame = frame.older()
  174. if select_frame is not None:
  175. select_frame.select()
  176. gdb.execute('frame')
  177. if message:
  178. print('DCHECK error: {}'.format(message))
  179. gdb.events.stop.connect(v8_stop_handler)
  180. end
  181. # Code imported from chromium/src/tools/gdb/gdbinit
  182. python
  183. import os
  184. import subprocess
  185. import sys
  186. compile_dirs = set()
  187. def get_current_debug_file_directories():
  188. dir = gdb.execute("show debug-file-directory", to_string=True)
  189. dir = dir[
  190. len('The directory where separate debug symbols are searched for is "'
  191. ):-len('".') - 1]
  192. return set(dir.split(":"))
  193. def add_debug_file_directory(dir):
  194. # gdb has no function to add debug-file-directory, simulates that by using
  195. # `show debug-file-directory` and `set debug-file-directory <directories>`.
  196. current_dirs = get_current_debug_file_directories()
  197. current_dirs.add(dir)
  198. gdb.execute(
  199. "set debug-file-directory %s" % ":".join(current_dirs), to_string=True)
  200. def newobj_handler(event):
  201. global compile_dirs
  202. compile_dir = os.path.dirname(event.new_objfile.filename)
  203. if not compile_dir:
  204. return
  205. if compile_dir in compile_dirs:
  206. return
  207. compile_dirs.add(compile_dir)
  208. # Add source path
  209. gdb.execute("dir %s" % compile_dir)
  210. # Need to tell the location of .dwo files.
  211. # https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
  212. # https://crbug.com/603286#c35
  213. add_debug_file_directory(compile_dir)
  214. # Event hook for newly loaded objfiles.
  215. # https://sourceware.org/gdb/onlinedocs/gdb/Events-In-Python.html
  216. gdb.events.new_objfile.connect(newobj_handler)
  217. gdb.execute("set environment V8_GDBINIT_SOURCED=1")
  218. end