blob: ad7847df318d293b1e99510d44398516e590076c [file] [log] [blame]
Andrew Topef837fa2017-10-04 22:44:25 -07001# 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
Andrew Top63c7ad42019-11-25 16:10:13 -08005# Print tagged object.
Andrew Topef837fa2017-10-04 22:44:25 -07006define job
Andrew Top63c7ad42019-11-25 16:10:13 -08007call (void) _v8_internal_Print_Object((void*)($arg0))
Andrew Topef837fa2017-10-04 22:44:25 -07008end
9document job
10Print a v8 JavaScript object
11Usage: job tagged_ptr
12end
13
Andrew Top63c7ad42019-11-25 16:10:13 -080014# Print content of v8::internal::Handle.
15define jh
16call (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).location_))
17end
18document jh
19Print content of a v8::internal::Handle
20Usage: jh internal_handle
21end
22
23# Print content of v8::Local handle.
Andrew Topef837fa2017-10-04 22:44:25 -070024define jlh
Andrew Top63c7ad42019-11-25 16:10:13 -080025call (void) _v8_internal_Print_Object(*((v8::internal::Object**)($arg0).val_))
Andrew Topef837fa2017-10-04 22:44:25 -070026end
27document jlh
28Print content of a v8::Local handle
29Usage: jlh local_handle
30end
31
32# Print Code objects containing given PC.
33define jco
Andrew Top63c7ad42019-11-25 16:10:13 -080034call (void) _v8_internal_Print_Code((void*)($arg0))
Andrew Topef837fa2017-10-04 22:44:25 -070035end
36document jco
37Print a v8 Code object from an internal code address
38Usage: jco pc
39end
40
Andrew Topef837fa2017-10-04 22:44:25 -070041# Print LayoutDescriptor.
42define jld
Andrew Top63c7ad42019-11-25 16:10:13 -080043call (void) _v8_internal_Print_LayoutDescriptor((void*)($arg0))
Andrew Topef837fa2017-10-04 22:44:25 -070044end
45document jld
46Print a v8 LayoutDescriptor object
47Usage: jld tagged_ptr
48end
49
Andrew Topef837fa2017-10-04 22:44:25 -070050# Print TransitionTree.
51define jtt
Andrew Top63c7ad42019-11-25 16:10:13 -080052call (void) _v8_internal_Print_TransitionTree((void*)($arg0))
Andrew Topef837fa2017-10-04 22:44:25 -070053end
54document jtt
55Print the complete transition tree of the given v8 Map.
56Usage: jtt tagged_ptr
57end
58
59# Print JavaScript stack trace.
60define jst
Andrew Top63c7ad42019-11-25 16:10:13 -080061call (void) _v8_internal_Print_StackTrace()
Andrew Topef837fa2017-10-04 22:44:25 -070062end
63document jst
64Print the current JavaScript stack trace
65Usage: jst
66end
67
Andrew Top63c7ad42019-11-25 16:10:13 -080068# Print TurboFan graph node.
69define pn
70call _v8_internal_Node_Print((void*)($arg0))
71end
72document pn
73Print a v8 TurboFan graph node
74Usage: pn node_address
75end
76
Andrew Topef837fa2017-10-04 22:44:25 -070077# Skip the JavaScript stack.
78define jss
79set $js_entry_sp=v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_
80set $rbp=*(void**)$js_entry_sp
81set $rsp=$js_entry_sp + 2*sizeof(void*)
82set $pc=*(void**)($js_entry_sp+sizeof(void*))
83end
84document jss
85Skip the jitted stack on x64 to where we entered JS last.
86Usage: jss
87end
88
89# Print stack trace with assertion scopes.
90define bta
91python
92import re
93frame_re = re.compile("^#(\d+)\s*(?:0x[a-f\d]+ in )?(.+) \(.+ at (.+)")
Andrew Top63c7ad42019-11-25 16:10:13 -080094assert_re = re.compile("^\s*(\S+) = .+<v8::internal::Per\w+AssertScope<v8::internal::(\S*), (false|true)>")
Andrew Topef837fa2017-10-04 22:44:25 -070095btl = gdb.execute("backtrace full", to_string = True).splitlines()
96for l in btl:
97 match = frame_re.match(l)
98 if match:
99 print("[%-2s] %-60s %-40s" % (match.group(1), match.group(2), match.group(3)))
100 match = assert_re.match(l)
101 if match:
102 if match.group(3) == "false":
103 prefix = "Disallow"
104 color = "\033[91m"
105 else:
106 prefix = "Allow"
107 color = "\033[92m"
108 print("%s -> %s %s (%s)\033[0m" % (color, prefix, match.group(2), match.group(1)))
109end
110end
111document bta
112Print stack trace with assertion scopes
113Usage: bta
114end
115
116# Search for a pointer inside all valid pages.
117define space_find
118 set $space = $arg0
Andrew Top63c7ad42019-11-25 16:10:13 -0800119 set $current_page = $space->first_page()
120 while ($current_page != 0)
Andrew Topef837fa2017-10-04 22:44:25 -0700121 printf "# Searching in %p - %p\n", $current_page->area_start(), $current_page->area_end()-1
122 find $current_page->area_start(), $current_page->area_end()-1, $arg1
123 set $current_page = $current_page->next_page()
124 end
125end
126
127define heap_find
128 set $heap = v8::internal::Isolate::Current()->heap()
129 printf "# Searching for %p in old_space ===============================\n", $arg0
130 space_find $heap->old_space() ($arg0)
131 printf "# Searching for %p in map_space ===============================\n", $arg0
132 space_find $heap->map_space() $arg0
133 printf "# Searching for %p in code_space ===============================\n", $arg0
134 space_find $heap->code_space() $arg0
135end
136document heap_find
137Find the location of a given address in V8 pages.
138Usage: heap_find address
139end
140
141set disassembly-flavor intel
142set disable-randomization off
Andrew Top63c7ad42019-11-25 16:10:13 -0800143
144# Install a handler whenever the debugger stops due to a signal. It walks up the
145# stack looking for V8_Dcheck and moves the frame to the one above it so it's
146# immediately at the line of code that triggered the DCHECK.
147python
148def dcheck_stop_handler(event):
149 frame = gdb.selected_frame()
150 select_frame = None
151 message = None
152 count = 0
153 # limit stack scanning since they're usually shallow and otherwise stack
154 # overflows can be very slow.
155 while frame is not None and count < 5:
156 count += 1
157 if frame.name() == 'V8_Dcheck':
158 frame_message = gdb.lookup_symbol('message', frame.block())[0]
159 if frame_message:
160 message = frame_message.value(frame).string()
161 select_frame = frame.older()
162 break
163 if frame.name() is not None and frame.name().startswith('V8_Fatal'):
164 select_frame = frame.older()
165 frame = frame.older()
166
167 if select_frame is not None:
168 select_frame.select()
169 gdb.execute('frame')
170 if message:
171 print('DCHECK error: {}'.format(message))
172
173gdb.events.stop.connect(dcheck_stop_handler)
174end
175
176# Code imported from chromium/src/tools/gdb/gdbinit
177python
178
179import os
180import subprocess
181import sys
182
183compile_dirs = set()
184
185
186def get_current_debug_file_directories():
187 dir = gdb.execute("show debug-file-directory", to_string=True)
188 dir = dir[
189 len('The directory where separate debug symbols are searched for is "'
190 ):-len('".') - 1]
191 return set(dir.split(":"))
192
193
194def add_debug_file_directory(dir):
195 # gdb has no function to add debug-file-directory, simulates that by using
196 # `show debug-file-directory` and `set debug-file-directory <directories>`.
197 current_dirs = get_current_debug_file_directories()
198 current_dirs.add(dir)
199 gdb.execute(
200 "set debug-file-directory %s" % ":".join(current_dirs), to_string=True)
201
202
203def newobj_handler(event):
204 global compile_dirs
205 compile_dir = os.path.dirname(event.new_objfile.filename)
206 if not compile_dir:
207 return
208 if compile_dir in compile_dirs:
209 return
210 compile_dirs.add(compile_dir)
211
212 # Add source path
213 gdb.execute("dir %s" % compile_dir)
214
215 # Need to tell the location of .dwo files.
216 # https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
217 # https://crbug.com/603286#c35
218 add_debug_file_directory(compile_dir)
219
220# Event hook for newly loaded objfiles.
221# https://sourceware.org/gdb/onlinedocs/gdb/Events-In-Python.html
222gdb.events.new_objfile.connect(newobj_handler)
223
224gdb.execute("set environment V8_GDBINIT_SOURCED=1")
225
226end