• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 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# Load this file by adding this to your ~/.lldbinit:
6# command script import <this_dir>/lldb_commands.py
7
8import lldb
9import re
10
11#####################
12# Helper functions. #
13#####################
14def current_thread(debugger):
15  return debugger.GetSelectedTarget().GetProcess().GetSelectedThread()
16
17def current_frame(debugger):
18  return current_thread(debugger).GetSelectedFrame()
19
20def no_arg_cmd(debugger, cmd):
21  current_frame(debugger).EvaluateExpression(cmd)
22  print("")
23
24def ptr_arg_cmd(debugger, name, param, cmd):
25  if not param:
26    print("'{}' requires an argument".format(name))
27    return
28  param = '(void*)({})'.format(param)
29  no_arg_cmd(debugger, cmd.format(param))
30
31#####################
32# lldb commands.    #
33#####################
34def job(debugger, param, *args):
35  """Print a v8 heap object"""
36  ptr_arg_cmd(debugger, 'job', param, "_v8_internal_Print_Object({})")
37
38def jlh(debugger, param, *args):
39  """Print v8::Local handle value"""
40  ptr_arg_cmd(debugger, 'jlh', param,
41              "_v8_internal_Print_Object(*(v8::internal::Object**)(*{}))")
42
43def jco(debugger, param, *args):
44  """Print the code object at the given pc (default: current pc)"""
45  if not param:
46    param = str(current_frame(debugger).FindRegister("pc").value)
47  ptr_arg_cmd(debugger, 'jco', param, "_v8_internal_Print_Code({})")
48
49def jld(debugger, param, *args):
50  """Print a v8 LayoutDescriptor object"""
51  ptr_arg_cmd(debugger, 'jld', param,
52              "_v8_internal_Print_LayoutDescriptor({})")
53
54def jtt(debugger, param, *args):
55  """Print the transition tree of a v8 Map"""
56  ptr_arg_cmd(debugger, 'jtt', param, "_v8_internal_Print_TransitionTree({})")
57
58def jst(debugger, *args):
59  """Print the current JavaScript stack trace"""
60  no_arg_cmd(debugger, "_v8_internal_Print_StackTrace()")
61
62def jss(debugger, *args):
63  """Skip the jitted stack on x64 to where we entered JS last"""
64  frame = current_frame(debugger)
65  js_entry_sp = frame.EvaluateExpression(
66      "v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_;") \
67       .GetValue()
68  sizeof_void = frame.EvaluateExpression("sizeof(void*)").GetValue()
69  rbp = frame.FindRegister("rbp")
70  rsp = frame.FindRegister("rsp")
71  pc = frame.FindRegister("pc")
72  rbp = js_entry_sp
73  rsp = js_entry_sp + 2 *sizeof_void
74  pc.value = js_entry_sp + sizeof_void
75
76def bta(debugger, *args):
77  """Print stack trace with assertion scopes"""
78  func_name_re = re.compile("([^(<]+)(?:\(.+\))?")
79  assert_re = re.compile(
80      "^v8::internal::Per\w+AssertType::(\w+)_ASSERT, (false|true)>")
81  thread = current_thread(debugger)
82  for frame in thread:
83    functionSignature = frame.GetDisplayFunctionName()
84    if functionSignature is None:
85      continue
86    functionName = func_name_re.match(functionSignature)
87    line = frame.GetLineEntry().GetLine()
88    sourceFile = frame.GetLineEntry().GetFileSpec().GetFilename()
89    if line:
90      sourceFile = sourceFile + ":" + str(line)
91
92    if sourceFile is None:
93      sourceFile = ""
94    print("[%-2s] %-60s %-40s" % (frame.GetFrameID(),
95                                  functionName.group(1),
96                                  sourceFile))
97    match = assert_re.match(str(functionSignature))
98    if match:
99      if match.group(3) == "false":
100        prefix = "Disallow"
101        color = "\033[91m"
102      else:
103        prefix = "Allow"
104        color = "\033[92m"
105      print("%s -> %s %s (%s)\033[0m" % (
106          color, prefix, match.group(2), match.group(1)))
107
108def __lldb_init_module(debugger, dict):
109  debugger.HandleCommand('settings set target.x86-disassembly-flavor intel')
110  for cmd in ('job', 'jlh', 'jco', 'jld', 'jtt', 'jst', 'jss', 'bta'):
111    debugger.HandleCommand(
112      'command script add -f lldb_commands.{} {}'.format(cmd, cmd))
113