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 5# Print HeapObjects. 6define job 7call _v8_internal_Print_Object((void*)($arg0)) 8end 9document job 10Print a v8 JavaScript object 11Usage: job tagged_ptr 12end 13 14# Print v8::Local handle value. 15define jlh 16call _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).val_)) 17end 18document jlh 19Print content of a v8::Local handle 20Usage: jlh local_handle 21end 22 23# Print Code objects containing given PC. 24define jco 25call _v8_internal_Print_Code((void*)($arg0)) 26end 27document jco 28Print a v8 Code object from an internal code address 29Usage: jco pc 30end 31 32# Print LayoutDescriptor. 33define jld 34call _v8_internal_Print_LayoutDescriptor((void*)($arg0)) 35end 36document jld 37Print a v8 LayoutDescriptor object 38Usage: jld tagged_ptr 39end 40 41# Print TransitionTree. 42define jtt 43call _v8_internal_Print_TransitionTree((void*)($arg0)) 44end 45document jtt 46Print the complete transition tree of the given v8 Map. 47Usage: jtt tagged_ptr 48end 49 50# Print JavaScript stack trace. 51define jst 52call _v8_internal_Print_StackTrace() 53end 54document jst 55Print the current JavaScript stack trace 56Usage: jst 57end 58 59# Skip the JavaScript stack. 60define jss 61set $js_entry_sp=v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_ 62set $rbp=*(void**)$js_entry_sp 63set $rsp=$js_entry_sp + 2*sizeof(void*) 64set $pc=*(void**)($js_entry_sp+sizeof(void*)) 65end 66document jss 67Skip the jitted stack on x64 to where we entered JS last. 68Usage: jss 69end 70 71# Print stack trace with assertion scopes. 72define bta 73python 74import re 75frame_re = re.compile("^#(\d+)\s*(?:0x[a-f\d]+ in )?(.+) \(.+ at (.+)") 76assert_re = re.compile("^\s*(\S+) = .+<v8::internal::Per\w+AssertType::(\w+)_ASSERT, (false|true)>") 77btl = gdb.execute("backtrace full", to_string = True).splitlines() 78for l in btl: 79 match = frame_re.match(l) 80 if match: 81 print("[%-2s] %-60s %-40s" % (match.group(1), match.group(2), match.group(3))) 82 match = assert_re.match(l) 83 if match: 84 if match.group(3) == "false": 85 prefix = "Disallow" 86 color = "\033[91m" 87 else: 88 prefix = "Allow" 89 color = "\033[92m" 90 print("%s -> %s %s (%s)\033[0m" % (color, prefix, match.group(2), match.group(1))) 91end 92end 93document bta 94Print stack trace with assertion scopes 95Usage: bta 96end 97 98# Search for a pointer inside all valid pages. 99define space_find 100 set $space = $arg0 101 set $current_page = $space->anchor()->next_page() 102 while ($current_page != $space->anchor()) 103 printf "# Searching in %p - %p\n", $current_page->area_start(), $current_page->area_end()-1 104 find $current_page->area_start(), $current_page->area_end()-1, $arg1 105 set $current_page = $current_page->next_page() 106 end 107end 108 109define heap_find 110 set $heap = v8::internal::Isolate::Current()->heap() 111 printf "# Searching for %p in old_space ===============================\n", $arg0 112 space_find $heap->old_space() ($arg0) 113 printf "# Searching for %p in map_space ===============================\n", $arg0 114 space_find $heap->map_space() $arg0 115 printf "# Searching for %p in code_space ===============================\n", $arg0 116 space_find $heap->code_space() $arg0 117end 118document heap_find 119Find the location of a given address in V8 pages. 120Usage: heap_find address 121end 122 123set disassembly-flavor intel 124set disable-randomization off 125 126# Install a handler whenever the debugger stops due to a signal. It walks up the 127# stack looking for V8_Dcheck and moves the frame to the one above it so it's 128# immediately at the line of code that triggered the DCHECK. 129python 130def dcheck_stop_handler(event): 131 orig_frame = gdb.selected_frame() 132 frame = orig_frame 133 select_frame = None 134 while frame is not None: 135 if frame.name() in ('V8_Dcheck', 'V8_Fatal'): 136 select_frame = frame.older() 137 frame = frame.older() 138 139 if select_frame is not None: 140 select_frame.select() 141 gdb.execute('frame') 142 143gdb.events.stop.connect(dcheck_stop_handler) 144end 145