11cb0ef41Sopenharmony_ci# Copyright 2017 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# Load this file by adding this to your ~/.lldbinit: 61cb0ef41Sopenharmony_ci# command script import <this_dir>/lldb_commands.py 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci# for py2/py3 compatibility 91cb0ef41Sopenharmony_cifrom __future__ import print_function 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciimport os 121cb0ef41Sopenharmony_ciimport re 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciimport lldb 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci##################### 171cb0ef41Sopenharmony_ci# Helper functions. # 181cb0ef41Sopenharmony_ci##################### 191cb0ef41Sopenharmony_cidef current_thread(debugger): 201cb0ef41Sopenharmony_ci return debugger.GetSelectedTarget().GetProcess().GetSelectedThread() 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cidef current_frame(debugger): 231cb0ef41Sopenharmony_ci return current_thread(debugger).GetSelectedFrame() 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_cidef no_arg_cmd(debugger, cmd): 261cb0ef41Sopenharmony_ci cast_to_void_expr = '(void) {}'.format(cmd) 271cb0ef41Sopenharmony_ci evaluate_result = current_frame(debugger).EvaluateExpression(cast_to_void_expr) 281cb0ef41Sopenharmony_ci # When a void function is called the return value type is 0x1001 which 291cb0ef41Sopenharmony_ci # is specified in http://tiny.cc/bigskz. This does not indicate 301cb0ef41Sopenharmony_ci # an error so we check for that value below. 311cb0ef41Sopenharmony_ci kNoResult = 0x1001 321cb0ef41Sopenharmony_ci error = evaluate_result.GetError() 331cb0ef41Sopenharmony_ci if error.fail and error.value != kNoResult: 341cb0ef41Sopenharmony_ci print("Failed to evaluate command {} :".format(cmd)) 351cb0ef41Sopenharmony_ci print(error.description) 361cb0ef41Sopenharmony_ci else: 371cb0ef41Sopenharmony_ci print("") 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_cidef ptr_arg_cmd(debugger, name, param, cmd): 401cb0ef41Sopenharmony_ci if not param: 411cb0ef41Sopenharmony_ci print("'{}' requires an argument".format(name)) 421cb0ef41Sopenharmony_ci return 431cb0ef41Sopenharmony_ci param = '(void*)({})'.format(param) 441cb0ef41Sopenharmony_ci no_arg_cmd(debugger, cmd.format(param)) 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci##################### 471cb0ef41Sopenharmony_ci# lldb commands. # 481cb0ef41Sopenharmony_ci##################### 491cb0ef41Sopenharmony_cidef job(debugger, param, *args): 501cb0ef41Sopenharmony_ci """Print a v8 heap object""" 511cb0ef41Sopenharmony_ci ptr_arg_cmd(debugger, 'job', param, "_v8_internal_Print_Object({})") 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_cidef jlh(debugger, param, *args): 541cb0ef41Sopenharmony_ci """Print v8::Local handle value""" 551cb0ef41Sopenharmony_ci ptr_arg_cmd(debugger, 'jlh', param, 561cb0ef41Sopenharmony_ci "_v8_internal_Print_Object(*(v8::internal::Object**)({}.val_))") 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_cidef jco(debugger, param, *args): 591cb0ef41Sopenharmony_ci """Print the code object at the given pc (default: current pc)""" 601cb0ef41Sopenharmony_ci if not param: 611cb0ef41Sopenharmony_ci param = str(current_frame(debugger).FindRegister("pc").value) 621cb0ef41Sopenharmony_ci ptr_arg_cmd(debugger, 'jco', param, "_v8_internal_Print_Code({})") 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_cidef jtt(debugger, param, *args): 651cb0ef41Sopenharmony_ci """Print the transition tree of a v8 Map""" 661cb0ef41Sopenharmony_ci ptr_arg_cmd(debugger, 'jtt', param, "_v8_internal_Print_TransitionTree({})") 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_cidef jst(debugger, *args): 691cb0ef41Sopenharmony_ci """Print the current JavaScript stack trace""" 701cb0ef41Sopenharmony_ci no_arg_cmd(debugger, "_v8_internal_Print_StackTrace()") 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cidef jss(debugger, *args): 731cb0ef41Sopenharmony_ci """Skip the jitted stack on x64 to where we entered JS last""" 741cb0ef41Sopenharmony_ci frame = current_frame(debugger) 751cb0ef41Sopenharmony_ci js_entry_sp = frame.EvaluateExpression( 761cb0ef41Sopenharmony_ci "v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_;") \ 771cb0ef41Sopenharmony_ci .GetValue() 781cb0ef41Sopenharmony_ci sizeof_void = frame.EvaluateExpression("sizeof(void*)").GetValue() 791cb0ef41Sopenharmony_ci rbp = frame.FindRegister("rbp") 801cb0ef41Sopenharmony_ci rsp = frame.FindRegister("rsp") 811cb0ef41Sopenharmony_ci pc = frame.FindRegister("pc") 821cb0ef41Sopenharmony_ci rbp = js_entry_sp 831cb0ef41Sopenharmony_ci rsp = js_entry_sp + 2 *sizeof_void 841cb0ef41Sopenharmony_ci pc.value = js_entry_sp + sizeof_void 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_cidef bta(debugger, *args): 871cb0ef41Sopenharmony_ci """Print stack trace with assertion scopes""" 881cb0ef41Sopenharmony_ci func_name_re = re.compile("([^(<]+)(?:\(.+\))?") 891cb0ef41Sopenharmony_ci assert_re = re.compile( 901cb0ef41Sopenharmony_ci "^v8::internal::Per\w+AssertType::(\w+)_ASSERT, (false|true)>") 911cb0ef41Sopenharmony_ci thread = current_thread(debugger) 921cb0ef41Sopenharmony_ci for frame in thread: 931cb0ef41Sopenharmony_ci functionSignature = frame.GetDisplayFunctionName() 941cb0ef41Sopenharmony_ci if functionSignature is None: 951cb0ef41Sopenharmony_ci continue 961cb0ef41Sopenharmony_ci functionName = func_name_re.match(functionSignature) 971cb0ef41Sopenharmony_ci line = frame.GetLineEntry().GetLine() 981cb0ef41Sopenharmony_ci sourceFile = frame.GetLineEntry().GetFileSpec().GetFilename() 991cb0ef41Sopenharmony_ci if line: 1001cb0ef41Sopenharmony_ci sourceFile = sourceFile + ":" + str(line) 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci if sourceFile is None: 1031cb0ef41Sopenharmony_ci sourceFile = "" 1041cb0ef41Sopenharmony_ci print("[%-2s] %-60s %-40s" % (frame.GetFrameID(), 1051cb0ef41Sopenharmony_ci functionName.group(1), 1061cb0ef41Sopenharmony_ci sourceFile)) 1071cb0ef41Sopenharmony_ci match = assert_re.match(str(functionSignature)) 1081cb0ef41Sopenharmony_ci if match: 1091cb0ef41Sopenharmony_ci if match.group(3) == "false": 1101cb0ef41Sopenharmony_ci prefix = "Disallow" 1111cb0ef41Sopenharmony_ci color = "\033[91m" 1121cb0ef41Sopenharmony_ci else: 1131cb0ef41Sopenharmony_ci prefix = "Allow" 1141cb0ef41Sopenharmony_ci color = "\033[92m" 1151cb0ef41Sopenharmony_ci print("%s -> %s %s (%s)\033[0m" % ( 1161cb0ef41Sopenharmony_ci color, prefix, match.group(2), match.group(1))) 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_cidef setup_source_map_for_relative_paths(debugger): 1191cb0ef41Sopenharmony_ci # Copied from Chromium's tools/lldb/lldbinit.py. 1201cb0ef41Sopenharmony_ci # When relative paths are used for debug symbols, lldb cannot find source 1211cb0ef41Sopenharmony_ci # files. Set up a source map to point to V8's root. 1221cb0ef41Sopenharmony_ci this_dir = os.path.dirname(os.path.abspath(__file__)) 1231cb0ef41Sopenharmony_ci source_dir = os.path.join(this_dir, os.pardir) 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci debugger.HandleCommand( 1261cb0ef41Sopenharmony_ci 'settings set target.source-map ../.. ' + source_dir) 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_cidef __lldb_init_module(debugger, dict): 1301cb0ef41Sopenharmony_ci setup_source_map_for_relative_paths(debugger) 1311cb0ef41Sopenharmony_ci debugger.HandleCommand('settings set target.x86-disassembly-flavor intel') 1321cb0ef41Sopenharmony_ci for cmd in ('job', 'jlh', 'jco', 'jld', 'jtt', 'jst', 'jss', 'bta'): 1331cb0ef41Sopenharmony_ci debugger.HandleCommand( 1341cb0ef41Sopenharmony_ci 'command script add -f lldb_commands.{} {}'.format(cmd, cmd)) 135