[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master c3038bf5e1d: ; LLDB support cleanup and extension
From: |
Gerd Moellmann |
Subject: |
master c3038bf5e1d: ; LLDB support cleanup and extension |
Date: |
Mon, 16 Oct 2023 04:14:41 -0400 (EDT) |
branch: master
commit c3038bf5e1d79c3dfa83717a5a61ecc86116f04a
Author: Gerd Möllmann <gerd.moellmann@gmail.com>
Commit: Gerd Möllmann <gerd.moellmann@gmail.com>
; LLDB support cleanup and extension
---
etc/emacs_lldb.py | 113 +++++++++++++++++++++++++++++++-----------------------
1 file changed, 65 insertions(+), 48 deletions(-)
diff --git a/etc/emacs_lldb.py b/etc/emacs_lldb.py
index 24b127a1fb9..a4f066b79de 100644
--- a/etc/emacs_lldb.py
+++ b/etc/emacs_lldb.py
@@ -78,22 +78,22 @@ class Lisp_Object:
# Object construction/initialization.
def __init__(self, lisp_obj):
- self.lisp_obj = lisp_obj
- self.frame = lisp_obj.GetFrame()
+ self.tagged = lisp_obj
+ self.unsigned = None
self.lisp_type = None
self.pvec_type = None
- self.value = None
+ self.untagged = None
self.init_unsigned()
self.init_lisp_types()
self.init_values()
def init_unsigned(self):
- if self.lisp_obj.GetType().GetTypeClass() == lldb.eTypeClassStruct:
+ if self.tagged.GetType().GetTypeClass() == lldb.eTypeClassStruct:
# Lisp_Object is actually a struct.
- lisp_word = self.lisp_obj.GetValueForExpressionPath(".i")
+ lisp_word = self.tagged.GetValueForExpressionPath(".i")
self.unsigned = lisp_word.GetValueAsUnsigned()
else:
- self.unsigned = self.lisp_obj.GetValueAsUnsigned()
+ self.unsigned = self.tagged.GetValueAsUnsigned()
# Initialize self.lisp_type to the C Lisp_Type enumerator of the
# Lisp_Object, as a string. Initialize self.pvec_type likewise to
@@ -117,40 +117,38 @@ class Lisp_Object:
f">> More_Lisp_Bits::PSEUDOVECTOR_AREA_BITS)")
self.pvec_type = enumerator_name(typ)
- # Initialize self.value according to lisp_type and pvec_type.
+ # Initialize self.untagged according to lisp_type and pvec_type.
def init_values(self):
if self.lisp_type == "Lisp_Symbol":
offset = self.get_lisp_pointer("char").GetValueAsUnsigned()
- self.value = self.eval(f"(struct Lisp_Symbol *)"
+ self.untagged = self.eval(f"(struct Lisp_Symbol *)"
f" ((char *) &lispsym + {offset})",
True)
elif self.lisp_type == "Lisp_String":
- self.value = self.get_lisp_pointer("struct Lisp_String", True)
+ self.untagged = self.get_lisp_pointer("struct Lisp_String", True)
elif self.lisp_type == "Lisp_Vectorlike":
c_type = Lisp_Object.pvec2type[self.pvec_type]
- self.value = self.get_lisp_pointer(c_type, True)
+ self.untagged = self.get_lisp_pointer(c_type, True)
elif self.lisp_type == "Lisp_Cons":
- self.value = self.get_lisp_pointer("struct Lisp_Cons", True)
+ self.untagged = self.get_lisp_pointer("struct Lisp_Cons", True)
elif self.lisp_type == "Lisp_Float":
- self.value = self.get_lisp_pointer("struct Lisp_Float", True)
+ self.untagged = self.get_lisp_pointer("struct Lisp_Float", True)
elif self.lisp_type in ("Lisp_Int0", "Lisp_Int1"):
- self.value = self.eval(f"((EMACS_INT) {self.unsigned}) "
- f">> (GCTYPEBITS - 1)",
- True)
+ self.untagged = self.eval(f"((EMACS_INT) {self.unsigned}) "
+ f">> (GCTYPEBITS - 1)", True)
+ elif self.lisp_type == "Lisp_Type_Unused0":
+ self.untagged = self.unsigned
else:
- assert False, "Unknown Lisp type"
-
- # Create an SBValue for EXPR with name NAME.
- def create_value(self, name, expr):
- return self.lisp_obj.CreateValueFromExpression(name, expr)
+ assert False, f"Unknown Lisp type {self.lisp_type}"
# Evaluate EXPR in the context of the current frame.
def eval(self, expr, make_var=False):
+ frame = self.tagged.GetFrame()
if make_var:
- return self.frame.EvaluateExpression(expr)
+ return frame.EvaluateExpression(expr)
options = lldb.SBExpressionOptions()
options.SetSuppressPersistentResult(True)
- return self.frame.EvaluateExpression(expr, options)
+ return frame.EvaluateExpression(expr, options)
# Return an SBValue for this object denoting a pointer of type
# TYP*.
@@ -163,20 +161,20 @@ class Lisp_Object:
# Return None otherwise.
def get_string_data(self):
if self.lisp_type == "Lisp_String":
- return self.value.GetValueForExpressionPath("->u.s.data")
+ return self.untagged.GetValueForExpressionPath("->u.s.data")
return None
# if this is a Lisp_Symbol, return an SBBalue for its name.
# Return None otherwise.
def get_symbol_name(self):
if self.lisp_type == "Lisp_Symbol":
- name = self.value.GetValueForExpressionPath("->u.s.name")
+ name = self.untagged.GetValueForExpressionPath("->u.s.name")
return Lisp_Object(name).get_string_data()
return None
# Return a summary string for this object.
def summary(self):
- return str(self.value)
+ return str(self.untagged)
########################################################################
@@ -205,6 +203,15 @@ def xdebug_print(debugger, command, result, internal_dict):
"""Print Lisp_Objects using safe_debug_print()"""
debugger.HandleCommand(f"expr safe_debug_print({command})")
+def xcomplete(debugger, command, result, internal_dict):
+ """Print completions for COMMAND."""
+ interpreter = debugger.GetCommandInterpreter()
+ string_list = lldb.SBStringList()
+ interpreter.HandleCompletion(command, len(command), len(command),
+ -1, string_list)
+ for i in range(string_list.GetSize()):
+ result.AppendMessage(string_list.GetStringAtIndex(i))
+
########################################################################
# Formatters
@@ -213,40 +220,49 @@ def xdebug_print(debugger, command, result,
internal_dict):
def type_summary_Lisp_Object(obj, internal_dict):
return Lisp_Object(obj).summary()
-# Don't know at the moment how to use this outside of the LLDB gui
-# command. And it's still incomplete.
class Lisp_Object_Provider:
+ """Synthetic children provider for Lisp_Objects.
+ Supposedly only used by 'frame variable', where -P <n> can be used
+ to specify a printing depth. """
def __init__(self, valobj, internal_dict):
self.valobj = valobj
- self.lisp_obj = Lisp_Object(valobj)
- self.child = None
+ self.children = {}
def update(self):
- if self.lisp_obj.lisp_type == "Lisp_Symbol":
- self.child = self.lisp_obj.get_symbol_name().Clone("name")
- self.child.SetSyntheticChildGenerated(True)
- elif self.lisp_obj.lisp_type == "Lisp_String":
- self.child = self.lisp_obj.get_string_data().Clone("data")
- self.child.SetSyntheticChildGenerated(True)
- else:
- self.child = self.lisp_obj.value.Clone("untagged")
- self.child.SetSyntheticChildGenerated(True)
-
- def has_children(self):
- return True
+ lisp_obj = Lisp_Object(self.valobj)
+ lisp_type = lisp_obj.lisp_type
+ try:
+ if lisp_type == "Lisp_Symbol":
+ child = lisp_obj.get_symbol_name()
+ self.children["name"] = child
+ elif lisp_type == "Lisp_String":
+ child = lisp_obj.get_string_data()
+ self.children["data"] = child
+ elif lisp_type == "Lisp_Cons":
+ car = lisp_obj.untagged.GetValueForExpressionPath("->u.s.car")
+ cdr =
lisp_obj.untagged.GetValueForExpressionPath("->u.s.u.cdr")
+ self.children["car"] = car
+ self.children["cdr"] = cdr
+ else:
+ self.children["untagged"] = lisp_obj.untagged
+ except:
+ print(f"*** exception in child provider update for {lisp_type}")
+ pass
def num_children(self):
- return 1
+ return len(self.children)
def get_child_index(self, name):
- return 0
+ index = 0
+ for child_name, child in self.children:
+ if child_name == name:
+ return index
+ index = index + 1
+ return -1
- # This works insofar as struct frame * works, but it doesn't work
- # Lisp_Symbol, for example.
def get_child_at_index(self, index):
- if index != 0:
- return None
- return self.child
+ key = list(self.children)[index]
+ return self.children[key]
########################################################################
@@ -300,6 +316,7 @@ def enable_type_category(debugger, category):
def __lldb_init_module(debugger, internal_dict):
define_command(debugger, xbacktrace)
define_command(debugger, xdebug_print)
+ define_command(debugger, xcomplete)
define_type_summary(debugger, "Lisp_Object", type_summary_Lisp_Object)
define_type_synthetic(debugger, "Lisp_Object", Lisp_Object_Provider)
enable_type_category(debugger, "Emacs")
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master c3038bf5e1d: ; LLDB support cleanup and extension,
Gerd Moellmann <=