Fix and extend lldbinit
1) Define all commands in one file. 2) Add logic to make 'jco' print current pc by default. 3) Add a comment to explain how to load the lldb_commands.py file. 4) Minor refactorings. R=ahaas@chromium.org No-Try: true Bug: v8:7754 Change-Id: I553f2ce4cefedad05466c692a8665a570372b76a Reviewed-on: https://chromium-review.googlesource.com/1127892 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#54329}
This commit is contained in:
parent
fa4bcc4da0
commit
5b744bfbd4
@ -2,24 +2,66 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# Load this file by adding this to your ~/.lldbinit:
|
||||
# command script import <this_dir>/lldb_commands.py
|
||||
|
||||
import lldb
|
||||
import re
|
||||
|
||||
#####################
|
||||
# Helper functions. #
|
||||
#####################
|
||||
def current_thread(debugger):
|
||||
return debugger.GetSelectedTarget().GetProcess().GetSelectedThread()
|
||||
|
||||
def current_frame(debugger):
|
||||
return current_thread(debugger).GetSelectedFrame()
|
||||
|
||||
def no_arg_cmd(debugger, cmd):
|
||||
current_frame(debugger).EvaluateExpression(cmd)
|
||||
print("")
|
||||
|
||||
def ptr_arg_cmd(debugger, name, param, cmd):
|
||||
if not param:
|
||||
print("'{}' requires an argument".format(name))
|
||||
return
|
||||
param = '(void*)({})'.format(param)
|
||||
no_arg_cmd(debugger, cmd.format(param))
|
||||
|
||||
#####################
|
||||
# lldb commands. #
|
||||
#####################
|
||||
def job(debugger, param, *args):
|
||||
"""Print a v8 heap object"""
|
||||
ptr_arg_cmd(debugger, 'job', param, "_v8_internal_Print_Object({})")
|
||||
|
||||
def jlh(debugger, param, *args):
|
||||
"""Print v8::Local handle value"""
|
||||
ptr_arg_cmd(debugger, 'jlh', param,
|
||||
"_v8_internal_Print_Object(*(v8::internal::Object**)(*{}))")
|
||||
|
||||
def jco(debugger, param, *args):
|
||||
"""Print the code object at the given pc (default: current pc)"""
|
||||
if not param:
|
||||
param = str(current_frame(debugger).FindRegister("pc").value)
|
||||
ptr_arg_cmd(debugger, 'jco', param, "_v8_internal_Print_Code({})")
|
||||
|
||||
def jld(debugger, param, *args):
|
||||
"""Print a v8 LayoutDescriptor object"""
|
||||
ptr_arg_cmd(debugger, 'jld', param,
|
||||
"_v8_internal_Print_LayoutDescriptor({})")
|
||||
|
||||
def jtt(debugger, param, *args):
|
||||
"""Print the transition tree of a v8 Map"""
|
||||
ptr_arg_cmd(debugger, 'jtt', param, "_v8_internal_Print_TransitionTree({})")
|
||||
|
||||
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();")
|
||||
print("")
|
||||
no_arg_cmd(debugger, "_v8_internal_Print_StackTrace()")
|
||||
|
||||
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()
|
||||
frame = current_frame(debugger)
|
||||
js_entry_sp = frame.EvaluateExpression(
|
||||
"v8::internal::Isolate::Current()->thread_local_top()->js_entry_sp_;") \
|
||||
.GetValue()
|
||||
@ -36,10 +78,7 @@ def bta(debugger, *args):
|
||||
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()
|
||||
thread = current_thread(debugger)
|
||||
for frame in thread:
|
||||
functionSignature = frame.GetDisplayFunctionName()
|
||||
if functionSignature is None:
|
||||
@ -66,7 +105,8 @@ def bta(debugger, *args):
|
||||
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')
|
||||
def __lldb_init_module(debugger, dict):
|
||||
debugger.HandleCommand('settings set target.x86-disassembly-flavor intel')
|
||||
for cmd in ('job', 'jlh', 'jco', 'jld', 'jtt', 'jst', 'jss', 'bta'):
|
||||
debugger.HandleCommand(
|
||||
'command script add -f lldb_commands.{} {}'.format(cmd, cmd))
|
||||
|
@ -1,20 +0,0 @@
|
||||
# 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 LayoutDescriptor.
|
||||
command regex -h 'Print a v8 LayoutDescriptor object' jld 's/(.+)/expr -- '_v8_internal_Print_LayoutDescriptor((void*)(%1))/'
|
||||
|
||||
# Print TransitionTree.
|
||||
command regex -h 'Print the transition tree of a v8 Map' jtt 's/(.+)/expr -- '_v8_internal_Print_TransitionTree((void*)(%1))/'
|
||||
|
||||
command script import ~/lldb_commands.py
|
Loading…
Reference in New Issue
Block a user