Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
deps: backport ec1ffe3 from upstream V8
This commit adds lldbinit files from upstream V8 and also adds these so
that they get installed when `make install` is run.

Original commit message:

[tools] add lldbinit

    The goal of this commit is to add the equivalent to gdbinit but
    for lldb. I've tried to replicate the commands as close as possible
    but I'm unsure about the jss command and hoping to get some feedback
    on it in addition to the bta command which I'm not sure how/when
    this could be used. This is probably just inexperience on my part.

    The lldbinit file can be placed into a directory prefixed with dot
    (.lldbinit) and the python script is currently expected to be in the
    same directory. The path to the script can be changed manually if
    needed as well.

    NOTRY=true

    Review-Url: https://codereview.chromium.org/2758373002
    Cr-Commit-Position: refs/heads/master@{#44136}
  • Loading branch information
danbev committed Mar 27, 2017
commit 6e4f694f9d7def76f99a35612addbd24ec52ece3
72 changes: 72 additions & 0 deletions deps/v8/tools/lldb_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2017 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import lldb
import re

def jst(debugger, *args):
"""Print the current JavaScript stack trace"""
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
frame.EvaluateExpression("_v8_internal_Print_StackTrace();")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my system this needs to be frame.EvaluateExpression("(void)_v8_internal_Print_StackTrace();")
If you run it manually lldb says the expression needs a return type:

(lldb) p _v8_internal_Print_StackTrace()
error: '_v8_internal_Print_StackTrace' has unknown return type; cast the call to its declared return type

print("")

def jss(debugger, *args):
"""Skip the jitted stack on x64 to where we entered JS last"""
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
js_entry_sp = frame.EvaluateExpression(
"v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_;") \
.GetValue()
sizeof_void = frame.EvaluateExpression("sizeof(void*)").GetValue()
rbp = frame.FindRegister("rbp")
rsp = frame.FindRegister("rsp")
pc = frame.FindRegister("pc")
rbp = js_entry_sp
rsp = js_entry_sp + 2 *sizeof_void
pc.value = js_entry_sp + sizeof_void

def bta(debugger, *args):
"""Print stack trace with assertion scopes"""
func_name_re = re.compile("([^(<]+)(?:\(.+\))?")
assert_re = re.compile(
"^v8::internal::Per\w+AssertType::(\w+)_ASSERT, (false|true)>")
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
for frame in thread:
functionSignature = frame.GetDisplayFunctionName()
if functionSignature is None:
continue
functionName = func_name_re.match(functionSignature)
line = frame.GetLineEntry().GetLine()
sourceFile = frame.GetLineEntry().GetFileSpec().GetFilename()
if line:
sourceFile = sourceFile + ":" + str(line)

if sourceFile is None:
sourceFile = ""
print("[%-2s] %-60s %-40s" % (frame.GetFrameID(),
functionName.group(1),
sourceFile))
match = assert_re.match(str(functionSignature))
if match:
if match.group(3) == "false":
prefix = "Disallow"
color = "\033[91m"
else:
prefix = "Allow"
color = "\033[92m"
print("%s -> %s %s (%s)\033[0m" % (
color, prefix, match.group(2), match.group(1)))

def __lldb_init_module (debugger, dict):
debugger.HandleCommand('command script add -f lldb_commands.jst jst')
debugger.HandleCommand('command script add -f lldb_commands.jss jss')
debugger.HandleCommand('command script add -f lldb_commands.bta bta')
26 changes: 26 additions & 0 deletions deps/v8/tools/lldbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2017 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Print HeapObjects.
command regex -h 'Print a v8 JavaScript object' job 's/(.+)/expr -- '_v8_internal_Print_Object((void*)(%1))/'

# Print v8::Local handle value.
command regex -h 'Print content of a v8::Local handle' jlh 's/(.+)/expr -- '_v8_internal_Print_Object(*(v8::internal::Object**)(*%1))/'

# Print Code objects containing given PC.
command regex -h 'Print a v8 Code object from an internal code address' jco 's/(.+)/expr -- '_v8_internal_Print_Code((void*)(*%1))/'

# Print FeedbackVector
command regex -h 'Print a v8 FeedbackVector object' jfv 's/(.+)/expr -- '_v8_internal_Print_FeedbackVector((void*)(%1))/'

# Print DescriptorArray.
command regex -h 'Print a v8 DescriptorArray object' jda 's/(.+)/expr -- '_v8_internal_Print_DescriptorArray((void*)(%1))/'

# Print LayoutDescriptor.
command regex -h 'Print a v8 LayoutDescriptor object' jld 's/(.+)/expr -- '_v8_internal_Print_LayoutDescriptor((void*)(%1))/'

# Print TransitionArray.
command regex -h 'Print a v8 TransitionArray object' jta 's/(.+)/expr -- '_v8_internal_Print_TransitionArray((void*)(%1))/'

command script import ~/lldb_commands.py
2 changes: 2 additions & 0 deletions tools/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ def files(action):
action(['src/node.stp'], 'share/systemtap/tapset/')

action(['deps/v8/tools/gdbinit'], 'share/doc/node/')
action(['deps/v8/tools/lldbinit'], 'share/doc/node/')
action(['deps/v8/tools/lldb_commands.py'], 'share/doc/node/')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we install programs in shared/doc? #2123 did the same for gdbinit, and it seems it made sense for @ofrobots and @bnoordhuis, so I'm probably just missing something.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I understand now that these files need to be copied somewhere else as configuration files.


if 'freebsd' in sys.platform or 'openbsd' in sys.platform:
action(['doc/node.1'], 'man/man1/')
Expand Down