Working on lldb data formatting some more
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
|
||||
import lldb, signal, sys, time
|
||||
import lldb.formatters.Logger
|
||||
import codelldb.value
|
||||
|
||||
############################################################
|
||||
#
|
||||
# Store pointers to some important types and globals.
|
||||
#
|
||||
############################################################
|
||||
|
||||
|
||||
_FNameEntryType = None
|
||||
@@ -9,6 +16,28 @@ _FUObjectItemType = None
|
||||
_GNameBlocksDebug = None
|
||||
_GObjectArrayForDebugVisualizers = None
|
||||
|
||||
def _init_globals(target):
|
||||
global _FNameEntryType, _FNameEntryStride, _FUObjectItemType
|
||||
global _GNameBlocksDebug, _GObjectArrayForDebugVisualizers
|
||||
|
||||
_FNameEntryType = target.FindFirstType('FNameEntry')
|
||||
if not _FNameEntryType.IsValid():
|
||||
print('UEDataFormatter: FNameEntry type not found')
|
||||
_FNameEntryStride = _FNameEntryType.GetByteAlign()
|
||||
|
||||
_FUObjectItemType = target.FindFirstType('FUObjectItem')
|
||||
if not _FUObjectItemType.IsValid():
|
||||
print('UEDataFormatter: FUObjectItem type not found')
|
||||
|
||||
_GNameBlocksDebug = target.FindFirstGlobalVariable('GNameBlocksDebug')
|
||||
if not _GNameBlocksDebug.IsValid():
|
||||
print('UEDataFormatter: GNameBlocksDebug not found')
|
||||
|
||||
_GObjectArrayForDebugVisualizers = target.FindFirstGlobalVariable('GObjectArrayForDebugVisualizers')
|
||||
if not _GObjectArrayForDebugVisualizers.IsValid():
|
||||
print('UEDataFormatter: GObjectArrayForDebugVisualizers not found')
|
||||
|
||||
|
||||
############################################################
|
||||
#
|
||||
# A forwarding synth provider is a provider that
|
||||
@@ -952,83 +981,15 @@ def UObjectSummaryProvider(valobj, dict):
|
||||
# return 'expired'
|
||||
# return Object.Dereference().GetSummary() or ('0x%x' % addr)
|
||||
|
||||
def __lldb_init_module(debugger, dict):
|
||||
print("Running lldb_init_module")
|
||||
debugger.HandleCommand('type category delete UEDataFormatters')
|
||||
global _FNameEntryType, _FNameEntryStride, _FUObjectItemType
|
||||
global _GNameBlocksDebug, _GObjectArrayForDebugVisualizers
|
||||
target = debugger.GetSelectedTarget()
|
||||
_FNameEntryType = target.FindFirstType('FNameEntry')
|
||||
_FNameEntryStride = _FNameEntryType.GetByteAlign()
|
||||
_FUObjectItemType = target.FindFirstType('FUObjectItem')
|
||||
_GNameBlocksDebug = target.FindFirstGlobalVariable('GNameBlocksDebug')
|
||||
if not _GNameBlocksDebug.IsValid():
|
||||
print('UEDataFormatter: GNameBlocksDebug not found')
|
||||
_GObjectArrayForDebugVisualizers = target.FindFirstGlobalVariable('GObjectArrayForDebugVisualizers')
|
||||
if not _GObjectArrayForDebugVisualizers.IsValid():
|
||||
print('UEDataFormatter: GObjectArrayForDebugVisualizers not found')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UEFStringSummaryProvider -e FString -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UEFNameSummaryProvider -e FName -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TObjectPtrSynthProvider -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TObjectPtrSummaryProvider -e -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TStrongObjectPtrSynthProvider -x "^TStrongObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TStrongObjectPtrSummaryProvider -e -x "^TStrongObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TSharedPtrSynthProvider -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TSharedPtrSummaryProvider -e -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TSharedPtrSynthProvider -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TSharedPtrSummaryProvider -e -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakPtrSynthProvider -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakPtrSummaryProvider -e -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakObjectPtrSynthProvider -x "^TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakObjectPtrSummaryProvider -e -x "^TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakObjectPtrSynthProvider -x "^FWeakObjectPtr$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakObjectPtrSummaryProvider -e FWeakObjectPtr -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.UObjectSynthProvider UObject -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UObjectSummaryProvider -e UObject -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEUObjectBaseSummaryProvider -e UObjectBase -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEFFieldClassSummaryProvider -e FFieldClass -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEFFieldSummaryProvider -e FField -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEFWeakObjectPtrSummaryProvider -e FWeakObjectPtr -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UETWeakObjectPtrSynthProvider -x "TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UETWeakObjectPtrSynthProvider -x "TAutoWeakObjectPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEArraySynthProvider -x "TArray<.+,.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEArraySummaryProvider -e -x "TArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEBitArraySynthProvider -x "TBitArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEBitArraySummaryProvider -e -x "TBitArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UESparseArraySynthProvider -x "TSparseArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UESparseArraySummaryProvider -e -x "TSparseArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEChunkedArraySynthProvider -x "TChunkedArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEChunkedArraySummaryProvider -e -x "TChunkedArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UESetSynthProvider -x "TSet<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UESetSummaryProvider -e -x "TSet<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEMapSynthProvider -x "TMap<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEMapSummaryProvider -e -x "TMap<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEMapSynthProvider -x "TMapBase<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEMapSummaryProvider -e -x "TMapBase<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UETObjectPtrSynthProvider -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UETObjectPtrSummaryProvider -e -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UETSharedPtrSynthProvider -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UETSharedPtrSummaryProvider -e -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UETSharedPtrSynthProvider -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UETSharedPtrSummaryProvider -e -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UETWeakPtrSynthProvider -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UETWeakPtrSummaryProvider -e -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand("type category enable UEDataFormatters")
|
||||
|
||||
def _patch_codelldb_value():
|
||||
"""Patch codelldb.value.Value with Unreal-friendly navigation:
|
||||
- __getattr__ auto-derefs pointers and falls back to iterating
|
||||
children by GetName() (so base classes like 'UWidget' resolve).
|
||||
##############################################################
|
||||
#
|
||||
# The getattr which is built in to codelldb.value.Value
|
||||
# fails to fetch synthetic values. Monkey-patch it.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
This affects every /se and /py expression that uses Value — strictly
|
||||
more forgiving than the stock behavior (paths that used to fail now
|
||||
succeed), but it IS a global behavior change.
|
||||
"""
|
||||
try:
|
||||
from codelldb.value import Value
|
||||
except ImportError:
|
||||
return
|
||||
def __getattr__(self, name):
|
||||
def _value_getattr(self, name):
|
||||
sbv = self._Value__sbvalue
|
||||
if sbv.GetType().IsPointerType():
|
||||
sbv = sbv.Dereference()
|
||||
@@ -1041,68 +1002,15 @@ def _patch_codelldb_value():
|
||||
break
|
||||
if not child.IsValid():
|
||||
raise AttributeError("Attribute '%s' is not defined" % name)
|
||||
return Value(child)
|
||||
Value.__getattr__ = __getattr__
|
||||
return codelldb.value.Value(child)
|
||||
|
||||
_patch_codelldb_value()
|
||||
codelldb.value.Value.__getattr__ = _value_getattr
|
||||
|
||||
##############################################################
|
||||
#
|
||||
# FV
|
||||
#
|
||||
#############################################################
|
||||
|
||||
|
||||
def fv(expr):
|
||||
"""Evaluate a Python-syntax expression against the current frame's variables.
|
||||
|
||||
Every frame variable is pre-wrapped in a codelldb Value and placed in
|
||||
the eval globals, so e.g. fv("Widget.Object.SCompoundWidget") walks via
|
||||
the (patched) Value.__getattr__, fv("Arr[3].Field") works via
|
||||
Value.__getitem__, and arithmetic/comparisons work via Value's dunders.
|
||||
|
||||
Usage in Watch: /py fv("Widget.Object.SCompoundWidget.SWidget")
|
||||
"""
|
||||
from codelldb.value import Value
|
||||
frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
|
||||
eval_globals = {}
|
||||
for var in frame.GetVariables(True, True, True, True):
|
||||
name = var.GetName()
|
||||
if var.IsValid() and name:
|
||||
eval_globals[name] = Value(var)
|
||||
try:
|
||||
result = eval(expr, eval_globals, {})
|
||||
except Exception as e:
|
||||
return "<%s: %s>" % (type(e).__name__, e)
|
||||
if isinstance(result, Value):
|
||||
return Value.unwrap(result)
|
||||
return result
|
||||
|
||||
def fv2():
|
||||
frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
|
||||
top = frame.FindVariable('Top')
|
||||
if not top.IsValid():
|
||||
return
|
||||
widget = top.GetChildMemberWithName('Widget')
|
||||
if not widget.IsValid():
|
||||
return
|
||||
uwidget = FindNamedChild(widget, 'UWidget')
|
||||
if not uwidget.IsValid():
|
||||
return
|
||||
return uwidget
|
||||
|
||||
def FindNamedChild(value, name):
|
||||
for i in range(value.GetNumChildren()):
|
||||
child = value.GetChildAtIndex(i)
|
||||
if child.IsValid() and child.GetName() == name:
|
||||
return child
|
||||
return lldb.SBValue()
|
||||
|
||||
|
||||
##############################################################
|
||||
#
|
||||
# The standard repr for SBValue will recurse infinitely if you
|
||||
# provide useful synth providers for smart pointers
|
||||
# The standard repr for SBValue will recurse infinitely if
|
||||
# you provide useful synth providers for smart pointers.
|
||||
# Monkey-patch it.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
@@ -1126,3 +1034,44 @@ def _sbvalue_display(v):
|
||||
|
||||
lldb.SBValue.__repr__ = _sbvalue_repr
|
||||
|
||||
##############################################################
|
||||
#
|
||||
# Module Initialization
|
||||
#
|
||||
#############################################################
|
||||
|
||||
def __lldb_init_module(debugger, dict):
|
||||
print("Running lldb_init_module")
|
||||
_init_globals(debugger.GetSelectedTarget())
|
||||
debugger.HandleCommand('type category delete UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UEFStringSummaryProvider -e FString -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UEFNameSummaryProvider -e FName -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TObjectPtrSynthProvider -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TObjectPtrSummaryProvider -e -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TStrongObjectPtrSynthProvider -x "^TStrongObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TStrongObjectPtrSummaryProvider -e -x "^TStrongObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TSharedPtrSynthProvider -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TSharedPtrSummaryProvider -e -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TSharedPtrSynthProvider -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TSharedPtrSummaryProvider -e -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakPtrSynthProvider -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakPtrSummaryProvider -e -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakObjectPtrSynthProvider -x "^TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakObjectPtrSummaryProvider -e -x "^TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakObjectPtrSynthProvider -x "^FWeakObjectPtr$" -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakObjectPtrSummaryProvider -e FWeakObjectPtr -w UEDataFormatters')
|
||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.UObjectSynthProvider UObject -w UEDataFormatters')
|
||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UObjectSummaryProvider -e UObject -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEArraySynthProvider -x "TArray<.+,.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEArraySummaryProvider -e -x "TArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEBitArraySynthProvider -x "TBitArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEBitArraySummaryProvider -e -x "TBitArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UESparseArraySynthProvider -x "TSparseArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UESparseArraySummaryProvider -e -x "TSparseArray<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UESetSynthProvider -x "TSet<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UESetSummaryProvider -e -x "TSet<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEMapSynthProvider -x "TMap<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEMapSummaryProvider -e -x "TMap<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEMapSynthProvider -x "TMapBase<.+>$" -w UEDataFormatters')
|
||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEMapSummaryProvider -e -x "TMapBase<.+>$" -w UEDataFormatters')
|
||||
debugger.HandleCommand("type category enable UEDataFormatters")
|
||||
|
||||
Reference in New Issue
Block a user