xref: /third_party/node/deps/v8/tools/gdbinit (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci# Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci# found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci# Print tagged object.
61cb0ef41Sopenharmony_cidefine job
71cb0ef41Sopenharmony_cicall (void) _v8_internal_Print_Object((void*)($arg0))
81cb0ef41Sopenharmony_ciend
91cb0ef41Sopenharmony_cidocument job
101cb0ef41Sopenharmony_ciPrint a v8 JavaScript object
111cb0ef41Sopenharmony_ciUsage: job tagged_ptr
121cb0ef41Sopenharmony_ciend
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci# Print content of v8::internal::Handle.
151cb0ef41Sopenharmony_cidefine jh
161cb0ef41Sopenharmony_cicall (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).location_))
171cb0ef41Sopenharmony_ciend
181cb0ef41Sopenharmony_cidocument jh
191cb0ef41Sopenharmony_ciPrint content of a v8::internal::Handle
201cb0ef41Sopenharmony_ciUsage: jh internal_handle
211cb0ef41Sopenharmony_ciend
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci# Print content of v8::Local handle.
241cb0ef41Sopenharmony_cidefine jlh
251cb0ef41Sopenharmony_cicall (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).val_))
261cb0ef41Sopenharmony_ciend
271cb0ef41Sopenharmony_cidocument jlh
281cb0ef41Sopenharmony_ciPrint content of a v8::Local handle
291cb0ef41Sopenharmony_ciUsage: jlh local_handle
301cb0ef41Sopenharmony_ciend
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci# Print Code objects containing given PC.
331cb0ef41Sopenharmony_cidefine jco
341cb0ef41Sopenharmony_ci  if $argc == 0
351cb0ef41Sopenharmony_ci    call (void) _v8_internal_Print_Code((void*)($pc))
361cb0ef41Sopenharmony_ci  else
371cb0ef41Sopenharmony_ci    call (void) _v8_internal_Print_Code((void*)($arg0))
381cb0ef41Sopenharmony_ci  end
391cb0ef41Sopenharmony_ciend
401cb0ef41Sopenharmony_cidocument jco
411cb0ef41Sopenharmony_ciPrint a v8 Code object from an internal code address
421cb0ef41Sopenharmony_ciUsage: jco pc
431cb0ef41Sopenharmony_ciend
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci# Print TransitionTree.
461cb0ef41Sopenharmony_cidefine jtt
471cb0ef41Sopenharmony_cicall (void) _v8_internal_Print_TransitionTree((void*)($arg0))
481cb0ef41Sopenharmony_ciend
491cb0ef41Sopenharmony_cidocument jtt
501cb0ef41Sopenharmony_ciPrint the complete transition tree of the given v8 Map.
511cb0ef41Sopenharmony_ciUsage: jtt tagged_ptr
521cb0ef41Sopenharmony_ciend
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci# Print JavaScript stack trace.
551cb0ef41Sopenharmony_cidefine jst
561cb0ef41Sopenharmony_cicall (void) _v8_internal_Print_StackTrace()
571cb0ef41Sopenharmony_ciend
581cb0ef41Sopenharmony_cidocument jst
591cb0ef41Sopenharmony_ciPrint the current JavaScript stack trace
601cb0ef41Sopenharmony_ciUsage: jst
611cb0ef41Sopenharmony_ciend
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci# Print TurboFan graph node.
641cb0ef41Sopenharmony_cidefine pn
651cb0ef41Sopenharmony_cicall _v8_internal_Node_Print((void*)($arg0))
661cb0ef41Sopenharmony_ciend
671cb0ef41Sopenharmony_cidocument pn
681cb0ef41Sopenharmony_ciPrint a v8 TurboFan graph node
691cb0ef41Sopenharmony_ciUsage: pn node_address
701cb0ef41Sopenharmony_ciend
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci# Skip the JavaScript stack.
731cb0ef41Sopenharmony_cidefine jss
741cb0ef41Sopenharmony_ciset $js_entry_sp=v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_
751cb0ef41Sopenharmony_ciset $rbp=*(void**)$js_entry_sp
761cb0ef41Sopenharmony_ciset $rsp=$js_entry_sp + 2*sizeof(void*)
771cb0ef41Sopenharmony_ciset $pc=*(void**)($js_entry_sp+sizeof(void*))
781cb0ef41Sopenharmony_ciend
791cb0ef41Sopenharmony_cidocument jss
801cb0ef41Sopenharmony_ciSkip the jitted stack on x64 to where we entered JS last.
811cb0ef41Sopenharmony_ciUsage: jss
821cb0ef41Sopenharmony_ciend
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci# Execute a simulator command.
851cb0ef41Sopenharmony_cipython
861cb0ef41Sopenharmony_ciimport gdb
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ciclass SimCommand(gdb.Command):
891cb0ef41Sopenharmony_ci  """Sim the current program."""
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  def __init__ (self):
921cb0ef41Sopenharmony_ci    super (SimCommand, self).__init__ ("sim", gdb.COMMAND_SUPPORT)
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  def invoke (self, arg, from_tty):
951cb0ef41Sopenharmony_ci    arg_c_string = gdb.Value(arg)
961cb0ef41Sopenharmony_ci    cmd_func = gdb.selected_frame().read_var("_v8_internal_Simulator_ExecDebugCommand")
971cb0ef41Sopenharmony_ci    cmd_func(arg_c_string)
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciSimCommand()
1001cb0ef41Sopenharmony_ciend
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci# Print stack trace with assertion scopes.
1031cb0ef41Sopenharmony_cidefine bta
1041cb0ef41Sopenharmony_cipython
1051cb0ef41Sopenharmony_ciimport re
1061cb0ef41Sopenharmony_ciframe_re = re.compile("^#(\d+)\s*(?:0x[a-f\d]+ in )?(.+) \(.+ at (.+)")
1071cb0ef41Sopenharmony_ciassert_re = re.compile("^\s*(\S+) = .+<v8::internal::Per\w+AssertScope<v8::internal::(\S*), (false|true)>")
1081cb0ef41Sopenharmony_cibtl = gdb.execute("backtrace full", to_string = True).splitlines()
1091cb0ef41Sopenharmony_cifor l in btl:
1101cb0ef41Sopenharmony_ci  match = frame_re.match(l)
1111cb0ef41Sopenharmony_ci  if match:
1121cb0ef41Sopenharmony_ci    print("[%-2s] %-60s %-40s" % (match.group(1), match.group(2), match.group(3)))
1131cb0ef41Sopenharmony_ci  match = assert_re.match(l)
1141cb0ef41Sopenharmony_ci  if match:
1151cb0ef41Sopenharmony_ci    if match.group(3) == "false":
1161cb0ef41Sopenharmony_ci      prefix = "Disallow"
1171cb0ef41Sopenharmony_ci      color = "\033[91m"
1181cb0ef41Sopenharmony_ci    else:
1191cb0ef41Sopenharmony_ci      prefix = "Allow"
1201cb0ef41Sopenharmony_ci      color = "\033[92m"
1211cb0ef41Sopenharmony_ci    print("%s -> %s %s (%s)\033[0m" % (color, prefix, match.group(2), match.group(1)))
1221cb0ef41Sopenharmony_ciend
1231cb0ef41Sopenharmony_ciend
1241cb0ef41Sopenharmony_cidocument bta
1251cb0ef41Sopenharmony_ciPrint stack trace with assertion scopes
1261cb0ef41Sopenharmony_ciUsage: bta
1271cb0ef41Sopenharmony_ciend
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci# Search for a pointer inside all valid pages.
1301cb0ef41Sopenharmony_cidefine space_find
1311cb0ef41Sopenharmony_ci  set $space = $arg0
1321cb0ef41Sopenharmony_ci  set $current_page = $space->first_page()
1331cb0ef41Sopenharmony_ci  while ($current_page != 0)
1341cb0ef41Sopenharmony_ci    printf "#   Searching in %p - %p\n", $current_page->area_start(), $current_page->area_end()-1
1351cb0ef41Sopenharmony_ci    find $current_page->area_start(), $current_page->area_end()-1, $arg1
1361cb0ef41Sopenharmony_ci    set $current_page = $current_page->next_page()
1371cb0ef41Sopenharmony_ci  end
1381cb0ef41Sopenharmony_ciend
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_cidefine heap_find
1411cb0ef41Sopenharmony_ci  set $heap = v8::internal::Isolate::Current()->heap()
1421cb0ef41Sopenharmony_ci  printf "# Searching for %p in old_space  ===============================\n", $arg0
1431cb0ef41Sopenharmony_ci  space_find $heap->old_space() ($arg0)
1441cb0ef41Sopenharmony_ci  printf "# Searching for %p in map_space  ===============================\n", $arg0
1451cb0ef41Sopenharmony_ci  space_find $heap->map_space() $arg0
1461cb0ef41Sopenharmony_ci  printf "# Searching for %p in code_space ===============================\n", $arg0
1471cb0ef41Sopenharmony_ci  space_find $heap->code_space() $arg0
1481cb0ef41Sopenharmony_ciend
1491cb0ef41Sopenharmony_cidocument heap_find
1501cb0ef41Sopenharmony_ciFind the location of a given address in V8 pages.
1511cb0ef41Sopenharmony_ciUsage: heap_find address
1521cb0ef41Sopenharmony_ciend
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci# The 'disassembly-flavor' command is only available on i386 and x84_64.
1551cb0ef41Sopenharmony_cipython
1561cb0ef41Sopenharmony_citry:
1571cb0ef41Sopenharmony_ci  gdb.execute("set disassembly-flavor intel")
1581cb0ef41Sopenharmony_ciexcept gdb.error:
1591cb0ef41Sopenharmony_ci  pass
1601cb0ef41Sopenharmony_ciend
1611cb0ef41Sopenharmony_ciset disable-randomization off
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci# Install a handler whenever the debugger stops due to a signal. It walks up the
1641cb0ef41Sopenharmony_ci# stack looking for V8_Dcheck / V8_Fatal / OS::DebugBreak frame and moves the
1651cb0ef41Sopenharmony_ci# frame to the one above it so it's immediately at the line of code that
1661cb0ef41Sopenharmony_ci# triggered the stop condition.
1671cb0ef41Sopenharmony_cipython
1681cb0ef41Sopenharmony_cidef v8_stop_handler(event):
1691cb0ef41Sopenharmony_ci  frame = gdb.selected_frame()
1701cb0ef41Sopenharmony_ci  select_frame = None
1711cb0ef41Sopenharmony_ci  message = None
1721cb0ef41Sopenharmony_ci  count = 0
1731cb0ef41Sopenharmony_ci  # Limit stack scanning since the frames we look for are near the top anyway,
1741cb0ef41Sopenharmony_ci  # and otherwise stack overflows can be very slow.
1751cb0ef41Sopenharmony_ci  while frame is not None and count < 7:
1761cb0ef41Sopenharmony_ci    count += 1
1771cb0ef41Sopenharmony_ci    # If we are in a frame created by gdb (e.g. for `(gdb) call foo()`), gdb
1781cb0ef41Sopenharmony_ci    # emits a dummy frame between its stack and the program's stack. Abort the
1791cb0ef41Sopenharmony_ci    # walk if we see this frame.
1801cb0ef41Sopenharmony_ci    if frame.type() == gdb.DUMMY_FRAME: break
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci    if frame.name() == 'V8_Dcheck':
1831cb0ef41Sopenharmony_ci      frame_message = gdb.lookup_symbol('message', frame.block())[0]
1841cb0ef41Sopenharmony_ci      if frame_message:
1851cb0ef41Sopenharmony_ci        message = frame_message.value(frame).string()
1861cb0ef41Sopenharmony_ci      select_frame = frame.older()
1871cb0ef41Sopenharmony_ci      break
1881cb0ef41Sopenharmony_ci    if frame.name() is not None and frame.name().startswith('V8_Fatal'):
1891cb0ef41Sopenharmony_ci      select_frame = frame.older()
1901cb0ef41Sopenharmony_ci    if frame.name() == 'v8::base::OS::DebugBreak':
1911cb0ef41Sopenharmony_ci      select_frame = frame.older()
1921cb0ef41Sopenharmony_ci    frame = frame.older()
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci  if select_frame is not None:
1951cb0ef41Sopenharmony_ci    select_frame.select()
1961cb0ef41Sopenharmony_ci    gdb.execute('frame')
1971cb0ef41Sopenharmony_ci    if message:
1981cb0ef41Sopenharmony_ci      print('DCHECK error: {}'.format(message))
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_cigdb.events.stop.connect(v8_stop_handler)
2011cb0ef41Sopenharmony_ciend
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci# Code imported from chromium/src/tools/gdb/gdbinit
2041cb0ef41Sopenharmony_cipython
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ciimport os
2071cb0ef41Sopenharmony_ciimport subprocess
2081cb0ef41Sopenharmony_ciimport sys
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_cicompile_dirs = set()
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_cidef get_current_debug_file_directories():
2141cb0ef41Sopenharmony_ci  dir = gdb.execute("show debug-file-directory", to_string=True)
2151cb0ef41Sopenharmony_ci  dir = dir[
2161cb0ef41Sopenharmony_ci      len('The directory where separate debug symbols are searched for is "'
2171cb0ef41Sopenharmony_ci         ):-len('".') - 1]
2181cb0ef41Sopenharmony_ci  return set(dir.split(":"))
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_cidef add_debug_file_directory(dir):
2221cb0ef41Sopenharmony_ci  # gdb has no function to add debug-file-directory, simulates that by using
2231cb0ef41Sopenharmony_ci  # `show debug-file-directory` and `set debug-file-directory <directories>`.
2241cb0ef41Sopenharmony_ci  current_dirs = get_current_debug_file_directories()
2251cb0ef41Sopenharmony_ci  current_dirs.add(dir)
2261cb0ef41Sopenharmony_ci  gdb.execute(
2271cb0ef41Sopenharmony_ci      "set debug-file-directory %s" % ":".join(current_dirs), to_string=True)
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_cidef newobj_handler(event):
2311cb0ef41Sopenharmony_ci  global compile_dirs
2321cb0ef41Sopenharmony_ci  compile_dir = os.path.dirname(event.new_objfile.filename)
2331cb0ef41Sopenharmony_ci  if not compile_dir:
2341cb0ef41Sopenharmony_ci    return
2351cb0ef41Sopenharmony_ci  if compile_dir in compile_dirs:
2361cb0ef41Sopenharmony_ci    return
2371cb0ef41Sopenharmony_ci  compile_dirs.add(compile_dir)
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci  # Add source path
2401cb0ef41Sopenharmony_ci  gdb.execute("dir %s" % compile_dir)
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci  # Need to tell the location of .dwo files.
2431cb0ef41Sopenharmony_ci  # https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
2441cb0ef41Sopenharmony_ci  # https://crbug.com/603286#c35
2451cb0ef41Sopenharmony_ci  add_debug_file_directory(compile_dir)
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci# Event hook for newly loaded objfiles.
2481cb0ef41Sopenharmony_ci# https://sourceware.org/gdb/onlinedocs/gdb/Events-In-Python.html
2491cb0ef41Sopenharmony_cigdb.events.new_objfile.connect(newobj_handler)
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_cigdb.execute("set environment V8_GDBINIT_SOURCED=1")
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ciend
254