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