gdbinit 6.25 KB
Newer Older
1 2 3 4
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

5
# Print tagged object.
6
define job
7
call (void) _v8_internal_Print_Object((void*)($arg0))
8 9 10 11 12 13
end
document job
Print a v8 JavaScript object
Usage: job tagged_ptr
end

14 15
# Print content of v8::internal::Handle.
define jh
16
call (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).location_))
17 18 19 20 21 22 23
end
document jh
Print content of a v8::internal::Handle
Usage: jh internal_handle
end

# Print content of v8::Local handle.
24
define jlh
25
call (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).val_))
26 27 28 29 30 31
end
document jlh
Print content of a v8::Local handle
Usage: jlh local_handle
end

32 33
# Print Code objects containing given PC.
define jco
34
call (void) _v8_internal_Print_Code((void*)($arg0))
35 36 37 38 39 40
end
document jco
Print a v8 Code object from an internal code address
Usage: jco pc
end

41 42
# Print LayoutDescriptor.
define jld
43
call (void) _v8_internal_Print_LayoutDescriptor((void*)($arg0))
44 45 46 47 48 49
end
document jld
Print a v8 LayoutDescriptor object
Usage: jld tagged_ptr
end

50 51
# Print TransitionTree.
define jtt
52
call (void) _v8_internal_Print_TransitionTree((void*)($arg0))
53 54 55 56 57 58
end
document jtt
Print the complete transition tree of the given v8 Map.
Usage: jtt tagged_ptr
end

59
# Print JavaScript stack trace.
60
define jst
61
call (void) _v8_internal_Print_StackTrace()
62 63 64 65 66 67
end
document jst
Print the current JavaScript stack trace
Usage: jst
end

68 69 70 71 72 73 74 75 76
# Print TurboFan graph node.
define pn
call _v8_internal_Node_Print((void*)($arg0))
end
document pn
Print a v8 TurboFan graph node
Usage: pn node_address
end

77 78 79 80 81 82 83 84 85 86 87 88
# Skip the JavaScript stack.
define jss
set $js_entry_sp=v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_
set $rbp=*(void**)$js_entry_sp
set $rsp=$js_entry_sp + 2*sizeof(void*)
set $pc=*(void**)($js_entry_sp+sizeof(void*))
end
document jss
Skip the jitted stack on x64 to where we entered JS last.
Usage: jss
end

89 90 91 92
# Print stack trace with assertion scopes.
define bta
python
import re
93
frame_re = re.compile("^#(\d+)\s*(?:0x[a-f\d]+ in )?(.+) \(.+ at (.+)")
94
assert_re = re.compile("^\s*(\S+) = .+<v8::internal::Per\w+AssertScope<v8::internal::(\S*), (false|true)>")
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
btl = gdb.execute("backtrace full", to_string = True).splitlines()
for l in btl:
  match = frame_re.match(l)
  if match:
    print("[%-2s] %-60s %-40s" % (match.group(1), match.group(2), match.group(3)))
  match = assert_re.match(l)
  if match:
    if match.group(3) == "false":
      prefix = "Disallow"
      color = "\033[91m"
    else:
      prefix = "Allow"
      color = "\033[92m"
    print("%s -> %s %s (%s)\033[0m" % (color, prefix, match.group(2), match.group(1)))
end
110
end
111 112 113 114 115
document bta
Print stack trace with assertion scopes
Usage: bta
end

116 117 118
# Search for a pointer inside all valid pages.
define space_find
  set $space = $arg0
Yang Guo's avatar
Yang Guo committed
119 120
  set $current_page = $space->first_page()
  while ($current_page != 0)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    printf "#   Searching in %p - %p\n", $current_page->area_start(), $current_page->area_end()-1
    find $current_page->area_start(), $current_page->area_end()-1, $arg1
    set $current_page = $current_page->next_page()
  end
end

define heap_find
  set $heap = v8::internal::Isolate::Current()->heap()
  printf "# Searching for %p in old_space  ===============================\n", $arg0
  space_find $heap->old_space() ($arg0)
  printf "# Searching for %p in map_space  ===============================\n", $arg0
  space_find $heap->map_space() $arg0
  printf "# Searching for %p in code_space ===============================\n", $arg0
  space_find $heap->code_space() $arg0
end
document heap_find
Find the location of a given address in V8 pages.
Usage: heap_find address
end

141 142 143 144 145 146 147
# The 'disassembly-flavor' command is only available on i386 and x84_64.
python
try:
  gdb.execute("set disassembly-flavor intel")
except gdb.error:
  pass
end
148
set disable-randomization off
149 150 151 152 153 154

# Install a handler whenever the debugger stops due to a signal. It walks up the
# stack looking for V8_Dcheck and moves the frame to the one above it so it's
# immediately at the line of code that triggered the DCHECK.
python
def dcheck_stop_handler(event):
155
  frame = gdb.selected_frame()
156
  select_frame = None
157
  message = None
158 159 160
  count = 0
  # limit stack scanning since they're usually shallow and otherwise stack
  # overflows can be very slow.
161
  while frame is not None and count < 7:
162
    count += 1
163 164 165 166 167 168
    if frame.name() == 'V8_Dcheck':
      frame_message = gdb.lookup_symbol('message', frame.block())[0]
      if frame_message:
        message = frame_message.value(frame).string()
      select_frame = frame.older()
      break
169
    if frame.name() is not None and frame.name().startswith('V8_Fatal'):
170 171 172
      select_frame = frame.older()
    frame = frame.older()

173 174 175
  if select_frame is not None:
    select_frame.select()
    gdb.execute('frame')
176 177
    if message:
      print('DCHECK error: {}'.format(message))
178

179 180
gdb.events.stop.connect(dcheck_stop_handler)
end
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229

# Code imported from chromium/src/tools/gdb/gdbinit
python

import os
import subprocess
import sys

compile_dirs = set()


def get_current_debug_file_directories():
  dir = gdb.execute("show debug-file-directory", to_string=True)
  dir = dir[
      len('The directory where separate debug symbols are searched for is "'
         ):-len('".') - 1]
  return set(dir.split(":"))


def add_debug_file_directory(dir):
  # gdb has no function to add debug-file-directory, simulates that by using
  # `show debug-file-directory` and `set debug-file-directory <directories>`.
  current_dirs = get_current_debug_file_directories()
  current_dirs.add(dir)
  gdb.execute(
      "set debug-file-directory %s" % ":".join(current_dirs), to_string=True)


def newobj_handler(event):
  global compile_dirs
  compile_dir = os.path.dirname(event.new_objfile.filename)
  if not compile_dir:
    return
  if compile_dir in compile_dirs:
    return
  compile_dirs.add(compile_dir)

  # Add source path
  gdb.execute("dir %s" % compile_dir)

  # Need to tell the location of .dwo files.
  # https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
  # https://crbug.com/603286#c35
  add_debug_file_directory(compile_dir)

# Event hook for newly loaded objfiles.
# https://sourceware.org/gdb/onlinedocs/gdb/Events-In-Python.html
gdb.events.new_objfile.connect(newobj_handler)

230
gdb.execute("set environment V8_GDBINIT_SOURCED=1")
231 232

end