More work on data formatters
This commit is contained in:
@@ -1,26 +1,3 @@
|
|||||||
--- Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py.orig 2026-04-12 22:58:33.989318455 -0400
|
|
||||||
+++ Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py 2025-11-10 23:34:18.481538118 -0500
|
|
||||||
@@ -32,7 +32,7 @@
|
|
||||||
if DataVal == 0:
|
|
||||||
Val = 'NULL'
|
|
||||||
else:
|
|
||||||
- Expr = '(char16_t*)(%s)' % Data
|
|
||||||
+ Expr = '(char16_t*)(%s)' % DataVal
|
|
||||||
ValRef = valobj.CreateValueFromExpression('string', Expr)
|
|
||||||
Val = ValRef.GetSummary()
|
|
||||||
elif Type.IsReferenceType():
|
|
||||||
@@ -47,6 +47,11 @@
|
|
||||||
Expr = '(char16_t*)(%s)' % valobj.GetAddress()
|
|
||||||
ValRef = valobj.CreateValueFromExpression('string', Expr)
|
|
||||||
Val = ValRef.GetSummary()
|
|
||||||
+ else:
|
|
||||||
+ DataVal = valobj.GetValueAsUnsigned(0)
|
|
||||||
+ Expr = '(char16_t)(%s)' % DataVal
|
|
||||||
+ ValRef = valobj.CreateValueFromExpression('string', Expr)
|
|
||||||
+ Val = ValRef.GetSummary()
|
|
||||||
return Val
|
|
||||||
|
|
||||||
def UESignedCharSummaryProvider(valobj,dict):
|
|
||||||
--- Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp.orig 2026-04-12 22:58:34.075320964 -0400
|
--- Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp.orig 2026-04-12 22:58:34.075320964 -0400
|
||||||
+++ Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp 2026-04-12 23:03:40.139226303 -0400
|
+++ Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp 2026-04-12 23:03:40.139226303 -0400
|
||||||
@@ -149,7 +149,7 @@
|
@@ -149,7 +149,7 @@
|
||||||
|
|||||||
57
Plugins/UEWingman/Source/UEWingman/Handlers/Test_TMaps.h
Normal file
57
Plugins/UEWingman/Source/UEWingman/Handlers/Test_TMaps.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WingServer.h"
|
||||||
|
#include "WingBasics.h"
|
||||||
|
#include "Containers/BitArray.h"
|
||||||
|
#include "Containers/SparseArray.h"
|
||||||
|
#include "Test_TMaps.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UWing_Test_TMaps : public UWingHandler
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void Register() override
|
||||||
|
{
|
||||||
|
UWingServer::AddHandler(this,
|
||||||
|
TEXT("Constructs a small TMap, TBitArray, and TSparseArray so that "
|
||||||
|
"a developer can set a breakpoint and inspect them with the "
|
||||||
|
"lldb data formatters."));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Handle() override
|
||||||
|
{
|
||||||
|
TMap<int32, FString> Map;
|
||||||
|
Map.Add(1, TEXT("one"));
|
||||||
|
Map.Add(2, TEXT("two"));
|
||||||
|
Map.Add(3, TEXT("three"));
|
||||||
|
Map.Add(42, TEXT("forty-two"));
|
||||||
|
|
||||||
|
TBitArray<> Bits;
|
||||||
|
Bits.Add(true);
|
||||||
|
Bits.Add(false);
|
||||||
|
Bits.Add(true);
|
||||||
|
Bits.Add(true);
|
||||||
|
Bits.Add(false);
|
||||||
|
|
||||||
|
// Add a few entries, then remove a middle one so the live set is
|
||||||
|
// non-contiguous. Exercises the sparse-array formatter against a hole.
|
||||||
|
TSparseArray<FString> Sparse;
|
||||||
|
Sparse.Add(TEXT("alpha"));
|
||||||
|
int32 BetaIdx = Sparse.Add(TEXT("beta"));
|
||||||
|
Sparse.Add(TEXT("gamma"));
|
||||||
|
Sparse.Add(TEXT("delta"));
|
||||||
|
Sparse.RemoveAt(BetaIdx);
|
||||||
|
|
||||||
|
// Set a breakpoint on the following line to inspect Map, Bits, and Sparse.
|
||||||
|
WingOut::Stdout.Printf(TEXT("Test_TMaps: Map has %d entries, Bits has %d bits, Sparse has %d entries.\n"),
|
||||||
|
Map.Num(), Bits.Num(), Sparse.Num());
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -97,6 +97,37 @@ class StoredSynthProvider:
|
|||||||
def has_children(self):
|
def has_children(self):
|
||||||
return len(self.children) > 0
|
return len(self.children) > 0
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
#
|
||||||
|
# An Indexed synth provider exposes N integer-indexed
|
||||||
|
# children [0]..[N-1]. Subclasses set self.count in update()
|
||||||
|
# and override get_child_at_index(index) to return the SBValue
|
||||||
|
# for a given index (with their own range check).
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
MAX_ARRAY_CHILDREN = 50
|
||||||
|
|
||||||
|
class IndexedSynthProvider:
|
||||||
|
def __init__(self, valobj, dict):
|
||||||
|
self.valobj = valobj
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def num_children(self):
|
||||||
|
return min(self.count, MAX_ARRAY_CHILDREN)
|
||||||
|
|
||||||
|
def get_child_index(self, name):
|
||||||
|
try:
|
||||||
|
return int(name.lstrip('[').rstrip(']'))
|
||||||
|
except:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def has_children(self):
|
||||||
|
return self.count > 0
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
#
|
#
|
||||||
# Provider for FString
|
# Provider for FString
|
||||||
@@ -112,7 +143,7 @@ def UEFStringSummaryProvider(valobj, dict):
|
|||||||
valobj = valobj.Dereference()
|
valobj = valobj.Dereference()
|
||||||
elif sbtype.IsReferenceType():
|
elif sbtype.IsReferenceType():
|
||||||
valobj = valobj.Dereference()
|
valobj = valobj.Dereference()
|
||||||
tarray = valobj.GetChildMemberWithName('Data')
|
tarray = valobj.GetChildMemberWithName('Data').GetNonSyntheticValue()
|
||||||
array_num = tarray.GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
array_num = tarray.GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
||||||
if array_num < 0: return 'corrupted string'
|
if array_num < 0: return 'corrupted string'
|
||||||
if array_num == 0: return 'empty string'
|
if array_num == 0: return 'empty string'
|
||||||
@@ -349,638 +380,157 @@ def UObjectSummaryProvider(valobj, dict):
|
|||||||
class_addr = class_debug_ptr.GetValueAsUnsigned(0)
|
class_addr = class_debug_ptr.GetValueAsUnsigned(0)
|
||||||
if not class_addr:
|
if not class_addr:
|
||||||
return 'null'
|
return 'null'
|
||||||
return UEFNameSummaryProvider(
|
class_name = UEFNameSummaryProvider(
|
||||||
class_debug_ptr.Dereference().GetChildMemberWithName('NamePrivate'), dict)
|
class_debug_ptr.Dereference().GetChildMemberWithName('NamePrivate'), dict)
|
||||||
|
instance_name = UEFNameSummaryProvider(
|
||||||
# class UEChunkedArraySynthProvider:
|
raw.GetChildMemberWithName('NamePrivate'), dict)
|
||||||
|
return 'Class=%s Name=%s' % (class_name, instance_name)
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
############################################################
|
||||||
# self.valobj = valobj
|
#
|
||||||
|
# Providers for TArray
|
||||||
# def num_children(self):
|
#
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
############################################################
|
||||||
# try:
|
|
||||||
# NumElementsVal = self.NumElements.GetValueAsSigned(0)
|
def _resolve_tarray_data_addr(allocator):
|
||||||
# return NumElementsVal;
|
"""Returns the base address of the element data for any TArray allocator."""
|
||||||
# except:
|
# Heap allocator (TSizedHeapAllocator): has a Data pointer directly
|
||||||
# return 0;
|
data = allocator.GetChildMemberWithName('Data')
|
||||||
|
if data.IsValid():
|
||||||
# def get_child_index(self,name):
|
return data.GetValueAsUnsigned(0)
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
# Inline allocator (TSizedInlineAllocator): prefer SecondaryData.Data, fall back to InlineData
|
||||||
# try:
|
secondary = allocator.GetChildMemberWithName('SecondaryData')
|
||||||
# return int(name.lstrip('[').rstrip(']'))
|
if secondary.IsValid():
|
||||||
# except:
|
sec_data = secondary.GetChildMemberWithName('Data')
|
||||||
# return None
|
if sec_data.IsValid() and sec_data.GetValueAsUnsigned(0) != 0:
|
||||||
|
return sec_data.GetValueAsUnsigned(0)
|
||||||
# def get_child_at_index(self,index):
|
# Fixed allocator or inline allocator using inline storage
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
inline = allocator.GetChildMemberWithName('InlineData')
|
||||||
# logger >> "Retrieving child %s" % index
|
if inline.IsValid():
|
||||||
# Expr = '(unsigned)sizeof(%s::FChunk)/%s' % (self.valobj.GetType().GetUnqualifiedType().GetName(), self.ElementTypeSize)
|
return inline.GetLoadAddress()
|
||||||
# self.ChunkBytes = self.valobj.CreateValueFromExpression('[%s]' % index, Expr)
|
return 0
|
||||||
# self.ChunkBytesSize = self.ChunkBytes.GetValueAsUnsigned(0)
|
|
||||||
# assert self.ChunkBytesSize != 0
|
def _resolve_tarray(tarray_val):
|
||||||
|
"""Given an SBValue of a TArray, return (array_num, data_sbvalue) where
|
||||||
# Expr = '*(*(((%s**)%s)+%s)+%s)' % (self.ElementType.GetName(), self.AllocatorData.GetValue(), index / self.ChunkBytesSize, index % self.ChunkBytesSize)
|
data_sbvalue is a typed array of the TArray's element type. Returns
|
||||||
# return self.valobj.CreateValueFromExpression('[%s]' % index, Expr)
|
(0, None) if empty or unresolvable."""
|
||||||
|
tarray_val = tarray_val.GetNonSyntheticValue()
|
||||||
# def extract_type(self):
|
arr_type = tarray_val.GetType().GetUnqualifiedType()
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
if arr_type.IsReferenceType():
|
||||||
# ArrayType = self.valobj.GetType().GetUnqualifiedType()
|
arr_type = arr_type.GetDereferencedType()
|
||||||
# if ArrayType.IsReferenceType():
|
elif arr_type.IsPointerType():
|
||||||
# ArrayType = ArrayType.GetDereferencedType()
|
arr_type = arr_type.GetPointeeType()
|
||||||
# elif ArrayType.IsPointerType():
|
if arr_type.GetNumberOfTemplateArguments() == 0: return 0, None
|
||||||
# ArrayType = ArrayType.GetPointeeType()
|
array_num = tarray_val.GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
||||||
# if ArrayType.GetNumberOfTemplateArguments() > 0:
|
if array_num <= 0: return 0, None
|
||||||
# ElementType = ArrayType.GetTemplateArgumentType(0)
|
data_addr = _resolve_tarray_data_addr(tarray_val.GetChildMemberWithName('AllocatorInstance'))
|
||||||
# else:
|
if data_addr == 0: return 0, None
|
||||||
# ElementType = None
|
elem_type = arr_type.GetTemplateArgumentType(0)
|
||||||
# return ElementType
|
if elem_type.GetByteSize() == 0: return 0, None
|
||||||
|
target = tarray_val.GetTarget()
|
||||||
# def update(self):
|
data = target.CreateValueFromAddress(
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
'data', lldb.SBAddress(data_addr, target), elem_type.GetArrayType(array_num))
|
||||||
# try:
|
return array_num, data
|
||||||
# self.ElementType = self.extract_type()
|
|
||||||
# self.ElementTypeSize = self.ElementType.GetByteSize()
|
class TArraySynthProvider(IndexedSynthProvider):
|
||||||
# assert self.ElementTypeSize != 0
|
def get_child_at_index(self, index):
|
||||||
# self.NumElements = self.valobj.GetChildMemberWithName('NumElements')
|
if index < 0 or index >= self.count:
|
||||||
# self.Chunks = self.valobj.GetChildMemberWithName('Chunks')
|
return lldb.SBValue()
|
||||||
# self.ArrayNum = self.Chunks.GetChildMemberWithName('ArrayNum')
|
return self.data_array.GetChildAtIndex(index)
|
||||||
# self.AllocatorInstance = self.Chunks.GetChildMemberWithName('AllocatorInstance')
|
|
||||||
# self.AllocatorData = self.AllocatorInstance.GetChildMemberWithName('Data')
|
def update(self):
|
||||||
# except:
|
self.count, self.data_array = _resolve_tarray(self.valobj)
|
||||||
# pass
|
|
||||||
|
def TArraySummaryProvider(valobj, dict):
|
||||||
# def has_children(self):
|
raw = valobj.GetNonSyntheticValue()
|
||||||
# return True
|
array_num = raw.GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
||||||
|
if array_num < 0: return 'corrupted'
|
||||||
# def UEChunkedArraySummaryProvider(valobj,dict):
|
return 'size=%d' % array_num
|
||||||
# return 'size=%s' % valobj.GetNumChildren()
|
|
||||||
|
############################################################
|
||||||
# class UESparseArraySynthProvider:
|
#
|
||||||
|
# Provider for TBitArray
|
||||||
# def __init__(self, valobj, dict):
|
#
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
############################################################
|
||||||
# self.valobj = valobj
|
|
||||||
|
def _bitarray_words(bit_array_val):
|
||||||
# def num_children(self):
|
"""Given an SBValue of a TBitArray, return its backing uint32[] as an SBValue
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
(or None if the array is empty/unallocated)."""
|
||||||
# try:
|
bit_array_val = bit_array_val.GetNonSyntheticValue()
|
||||||
# NumBitsVal = self.NumFreeIndices.GetValueAsSigned(0)
|
num_bits = bit_array_val.GetChildMemberWithName('NumBits').GetValueAsSigned(0)
|
||||||
# ArrayNumVal = self.Data.GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
if num_bits <= 0: return None
|
||||||
# return ArrayNumVal - NumBitsVal;
|
allocator = bit_array_val.GetChildMemberWithName('AllocatorInstance')
|
||||||
# except:
|
data_addr = _resolve_tarray_data_addr(allocator)
|
||||||
# return 0;
|
if data_addr == 0: return None
|
||||||
|
target = bit_array_val.GetTarget()
|
||||||
# def get_child_index(self,name):
|
uint32_type = target.GetBasicType(lldb.eBasicTypeUnsignedInt)
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
num_words = (num_bits + 31) // 32
|
||||||
# try:
|
return target.CreateValueFromAddress(
|
||||||
# return int(name.lstrip('[').rstrip(']'))
|
'words', lldb.SBAddress(data_addr, target),
|
||||||
# except:
|
uint32_type.GetArrayType(num_words))
|
||||||
# return None
|
|
||||||
|
class TBitArraySynthProvider(IndexedSynthProvider):
|
||||||
# def get_child_at_index(self,index):
|
def get_child_at_index(self, index):
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
if index < 0 or index >= self.count:
|
||||||
# logger >> "Retrieving child %s" % index
|
return lldb.SBValue()
|
||||||
# if index < 0:
|
word = self.words.GetChildAtIndex(index)
|
||||||
# return None;
|
target = self.valobj.GetTarget()
|
||||||
|
child = target.CreateValueFromAddress(
|
||||||
# if index >= self.num_children():
|
'[%d]' % index, lldb.SBAddress(word.GetLoadAddress(), target),
|
||||||
# return None;
|
target.GetBasicType(lldb.eBasicTypeUnsignedInt))
|
||||||
|
child.SetFormat(lldb.eFormatBinary)
|
||||||
# Val = None
|
return child
|
||||||
# if self.SecondaryDataDataVal > 0:
|
|
||||||
# Expr = '(bool)((((int*)%s)[%s/32] >> %s) & 1)' % (self.SecondaryDataData.GetAddress(), index, index)
|
def update(self):
|
||||||
# Val = self.SecondaryDataData.CreateValueFromExpression('[%s]' % index, Expr)
|
self.count = 0
|
||||||
# else:
|
self.words = _bitarray_words(self.valobj)
|
||||||
# Expr = '(bool)((((int*)%s)[%s/32] >> %s) & 1)' % (self.InlineData.GetAddress(), index, index)
|
if self.words is None: return
|
||||||
# Val = self.InlineData.CreateValueFromExpression('[5s]' % index, Expr)
|
self.count = self.words.GetNumChildren()
|
||||||
|
|
||||||
# if Val.GetValueAsSigned(0) != 0:
|
def TBitArraySummaryProvider(valobj, dict):
|
||||||
# offset = index * self.ElementTypeSize
|
num_bits = valobj.GetNonSyntheticValue().GetChildMemberWithName('NumBits').GetValueAsSigned(0)
|
||||||
# return self.AllocatorData.CreateChildAtOffset('[%s]' % index, offset, self.ElementType)
|
return 'size=%d' % num_bits
|
||||||
# else:
|
|
||||||
# return None
|
############################################################
|
||||||
|
#
|
||||||
# def extract_type(self):
|
# Provider for TSparseArray
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
#
|
||||||
# ArrayType = self.valobj.GetType().GetUnqualifiedType()
|
############################################################
|
||||||
# if ArrayType.IsReferenceType():
|
|
||||||
# ArrayType = ArrayType.GetDereferencedType()
|
class TSparseArraySynthProvider(IndexedSynthProvider):
|
||||||
# elif ArrayType.IsPointerType():
|
def get_child_at_index(self, index):
|
||||||
# ArrayType = ArrayType.GetPointeeType()
|
if index < 0 or index >= self.count:
|
||||||
# if ArrayType.GetNumberOfTemplateArguments() > 0:
|
return lldb.SBValue()
|
||||||
# ElementType = ArrayType.GetTemplateArgumentType(0)
|
raw_idx = self.live_indices[index]
|
||||||
# else:
|
slot = self.data_array.GetChildAtIndex(raw_idx)
|
||||||
# ElementType = None
|
target = self.valobj.GetTarget()
|
||||||
# return ElementType
|
return target.CreateValueFromAddress(
|
||||||
|
'[%d]' % index,
|
||||||
# def update(self):
|
lldb.SBAddress(slot.GetLoadAddress(), target),
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
self.element_type)
|
||||||
# try:
|
|
||||||
# self.ElementType = self.extract_type()
|
def update(self):
|
||||||
# self.ElementTypeSize = self.ElementType.GetByteSize()
|
self.count = 0
|
||||||
# assert self.ElementTypeSize != 0
|
self.live_indices = []
|
||||||
# self.NumFreeIndices = self.valobj.GetChildMemberWithName('NumFreeIndices')
|
self.data_array = None
|
||||||
# self.Data = self.valobj.GetChildMemberWithName('Data')
|
self.element_type = None
|
||||||
# self.AllocatorInstance = self.Data.GetChildMemberWithName('AllocatorInstance')
|
array_num, data = _resolve_tarray(self.valobj.GetChildMemberWithName('Data'))
|
||||||
# self.AllocatorData = self.AllocatorInstance.GetChildMemberWithName('Data')
|
if data is None: return
|
||||||
# self.AllocationFlags = self.valobj.GetChildMemberWithName('AllocationFlags')
|
words = _bitarray_words(self.valobj.GetChildMemberWithName('AllocationFlags'))
|
||||||
# self.InlineData = self.AllocationFlags.GetChildMemberWithName('InlineData')
|
if words is None: return
|
||||||
# self.SecondaryData = self.AllocationFlags.GetChildMemberWithName('SecondaryData')
|
self.data_array = data
|
||||||
# self.SecondaryDataData = self.SecondaryData.GetChildMemberWithName('Data')
|
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
|
||||||
# self.SecondaryDataDataVal = self.SecondaryDataData.GetValueAsSigned(0)
|
for i in range(array_num):
|
||||||
# except:
|
word = words.GetChildAtIndex(i // 32).GetValueAsUnsigned(0)
|
||||||
# pass
|
if (word >> (i % 32)) & 1:
|
||||||
|
self.live_indices.append(i)
|
||||||
# def has_children(self):
|
self.count = len(self.live_indices)
|
||||||
# return True
|
|
||||||
|
def TSparseArraySummaryProvider(valobj, dict):
|
||||||
# def UESparseArraySummaryProvider(valobj,dict):
|
raw = valobj.GetNonSyntheticValue()
|
||||||
# return 'size=%s' % valobj.GetNumChildren()
|
array_num = raw.GetChildMemberWithName('Data').GetNonSyntheticValue().GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
||||||
|
num_free = raw.GetChildMemberWithName('NumFreeIndices').GetValueAsSigned(0)
|
||||||
# class UEBitArraySynthProvider:
|
return 'size=%d' % (array_num - num_free)
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# NumBitsVal = self.NumBits.GetValueAsSigned(0)
|
|
||||||
# return NumBitsVal;
|
|
||||||
# except:
|
|
||||||
# return 0;
|
|
||||||
|
|
||||||
# def get_child_index(self,name):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# return int(name.lstrip('[').rstrip(']'))
|
|
||||||
# except:
|
|
||||||
# return None
|
|
||||||
|
|
||||||
# def get_child_at_index(self,index):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# logger >> "Retrieving child %s" % index
|
|
||||||
# if index < 0:
|
|
||||||
# return None;
|
|
||||||
|
|
||||||
# if index >= self.num_children():
|
|
||||||
# return None;
|
|
||||||
|
|
||||||
# if self.SecondaryDataDataVal > 0:
|
|
||||||
# Expr = '(bool)((((int*)%s)[%s/32] >> %s) & 1)' % (self.SecondaryDataData.GetAddress(), index, index)
|
|
||||||
# return self.SecondaryDataData.CreateValueFromExpression('[%s]' % index, Expr)
|
|
||||||
# else:
|
|
||||||
# Expr = '(bool)((((int*)%s)[%s/32] >> %s) & 1)' % (self.InlineData.GetAddress(), index, index)
|
|
||||||
# return self.InlineData.CreateValueFromExpression('[%s]' % index, Expr)
|
|
||||||
|
|
||||||
# return None
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# self.SecondaryDataData = None
|
|
||||||
# self.SecondaryDataDataVal = 0
|
|
||||||
# self.NumBits = self.valobj.GetChildMemberWithName('NumBits')
|
|
||||||
# self.MaxBits = self.valobj.GetChildMemberWithName('MaxBits')
|
|
||||||
# self.InlineData = self.valobj.GetChildMemberWithName('InlineData')
|
|
||||||
# self.SecondaryData = self.valobj.GetChildMemberWithName('SecondaryData')
|
|
||||||
# if self.SecondaryData != None:
|
|
||||||
# self.SecondaryDataData = self.SecondaryData.GetChildMemberWithName('Data')
|
|
||||||
# self.SecondaryDataDataVal = self.SecondaryDataData.GetValueAsUnsigned(0)
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return True
|
|
||||||
|
|
||||||
# def UEBitArraySummaryProvider(valobj,dict):
|
|
||||||
# return 'size=%s' % valobj.GetNumChildren()
|
|
||||||
|
|
||||||
# class UEArraySynthProvider:
|
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# ArrayNumVal = self.ArrayNum.GetValueAsSigned(0)
|
|
||||||
# return ArrayNumVal + self.NumChildren;
|
|
||||||
# except:
|
|
||||||
# return 0;
|
|
||||||
|
|
||||||
# def get_child_index(self,name):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# return self.NumChildren + int(name.lstrip('[').rstrip(']'))
|
|
||||||
# except:
|
|
||||||
# return self.valobj.GetIndexOfChildWithName(name)
|
|
||||||
|
|
||||||
# def get_child_at_index(self,index):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# logger >> "Retrieving child %s" % index
|
|
||||||
# if index < 0:
|
|
||||||
# return None;
|
|
||||||
|
|
||||||
# if index < self.NumChildren:
|
|
||||||
# return self.valobj.GetChildAtIndex(index)
|
|
||||||
# else:
|
|
||||||
# index -= self.NumChildren
|
|
||||||
|
|
||||||
# if index >= self.num_children():
|
|
||||||
# return None;
|
|
||||||
# try:
|
|
||||||
# offset = index * self.ElementTypeSize
|
|
||||||
# if self.Data != None:
|
|
||||||
# return self.Data.CreateChildAtOffset('[%s]' % index, offset, self.ElementType)
|
|
||||||
# elif self.SecondaryDataDataVal > 0:
|
|
||||||
# return self.SecondaryDataData.CreateChildAtOffset('[%s]' % index, offset, self.ElementType)
|
|
||||||
# else:
|
|
||||||
# return self.InlineData.CreateChildAtOffset('[%s]' % index, offset, self.ElementType)
|
|
||||||
# except:
|
|
||||||
# return None
|
|
||||||
|
|
||||||
# def extract_type(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# ArrayType = self.valobj.GetType().GetUnqualifiedType()
|
|
||||||
# if ArrayType.IsReferenceType():
|
|
||||||
# ArrayType = ArrayType.GetDereferencedType()
|
|
||||||
# elif ArrayType.IsPointerType():
|
|
||||||
# ArrayType = ArrayType.GetPointeeType()
|
|
||||||
|
|
||||||
# if ArrayType.GetNumberOfTemplateArguments() > 0:
|
|
||||||
# ElementType = ArrayType.GetTemplateArgumentType(0)
|
|
||||||
# else:
|
|
||||||
# ElementType = None
|
|
||||||
# return ElementType
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# self.NumChildren = self.valobj.GetNumChildren()
|
|
||||||
# self.ArrayNum = self.valobj.GetChildMemberWithName('ArrayNum')
|
|
||||||
# self.ArrayMax = self.valobj.GetChildMemberWithName('ArrayMax')
|
|
||||||
# self.AllocatorInstance = self.valobj.GetChildMemberWithName('AllocatorInstance')
|
|
||||||
# if self.AllocatorInstance.GetType().IsReferenceType():
|
|
||||||
# self.AllocatorInstance = self.AllocatorInstance.Dereference()
|
|
||||||
# self.Data = self.AllocatorInstance.GetChildMemberWithName('Data')
|
|
||||||
# self.InlineData = self.AllocatorInstance.GetChildMemberWithName('InlineData')
|
|
||||||
# self.SecondaryData = self.AllocatorInstance.GetChildMemberWithName('SecondaryData')
|
|
||||||
# if self.SecondaryData != None:
|
|
||||||
# self.SecondaryDataData = self.SecondaryData.GetChildMemberWithName('Data')
|
|
||||||
# self.SecondaryDataDataVal = self.SecondaryDataData.GetValueAsUnsigned(0)
|
|
||||||
# else:
|
|
||||||
# self.SecondaryDataData = None
|
|
||||||
# self.SecondaryDataDataVal = 0
|
|
||||||
# except:
|
|
||||||
# logger >> "UEArraySynthProvider::update failed accessing members"
|
|
||||||
# pass
|
|
||||||
# try:
|
|
||||||
# self.ElementType = self.extract_type()
|
|
||||||
# self.ElementTypeSize = self.ElementType.GetByteSize()
|
|
||||||
# assert self.ElementTypeSize != 0
|
|
||||||
# except:
|
|
||||||
# logger >> "UEArraySynthProvider::update failed accessing element type"
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return True
|
|
||||||
|
|
||||||
# def UEArraySummaryProvider(valobj,dict):
|
|
||||||
# return 'size=%s' % valobj.GetChildMemberWithName('ArrayNum').GetValueAsSigned(0)
|
|
||||||
|
|
||||||
# class UESetSynthProvider:
|
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# # Can't cast to TSetElement - the template instantiation won't allow it
|
|
||||||
# Expr = '(size_t)sizeof(FSetElementId) + sizeof(int32)'
|
|
||||||
# self.TSetElement = self.valobj.CreateValueFromExpression('TSetElement', Expr)
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# ArrayNumVal = self.ArrayNum.GetValueAsUnsigned(0)
|
|
||||||
# NumFreeIndicesVal = self.NumFreeIndices.GetValueAsUnsigned(0)
|
|
||||||
# return ArrayNumVal - NumFreeIndicesVal;
|
|
||||||
# except:
|
|
||||||
# return 0;
|
|
||||||
|
|
||||||
# def get_child_index(self,name):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# return int(name.lstrip('[').rstrip(']'))
|
|
||||||
# except:
|
|
||||||
# return 0
|
|
||||||
|
|
||||||
# def get_child_at_index(self,index):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# logger >> "Retrieving child %s" % index
|
|
||||||
# if index < 0:
|
|
||||||
# return None;
|
|
||||||
|
|
||||||
# if index >= self.num_children():
|
|
||||||
# return None;
|
|
||||||
# try:
|
|
||||||
# offset = index * self.ElementTypeSize
|
|
||||||
# HasObject = 0
|
|
||||||
# if self.SecondaryDataDataVal > 0:
|
|
||||||
# Expr = '(bool)((((int*)%s)[%s/32] >> %s) & 1)' % (self.SecondaryDataDataVal, index, index)
|
|
||||||
# HasObject = 1 ##self.AllocationFlagsSecondaryDataData.CreateValueFromExpression('[%s]' % index, Expr).GetValueAsUnsigned(0)
|
|
||||||
# else:
|
|
||||||
# Expr = '(bool)((((int*)%s)[%s/32] >> %s) & 1)' % (self.AllocationFlagsInlineDataAddr, index, index)
|
|
||||||
# HasObject = 1 ##self.AllocationFlagsInlineData.CreateValueFromExpression('[%s]' % index, Expr).GetValueAsUnsigned(0)
|
|
||||||
|
|
||||||
# if HasObject == 1:
|
|
||||||
# return self.AllocatorInstanceData.CreateChildAtOffset('[%s]' % index, offset, self.ElementType)
|
|
||||||
# else:
|
|
||||||
# return self.valobj.CreateValueFromExpression('[%s]' % index, '(void*)0xDEADBEEF')
|
|
||||||
# except:
|
|
||||||
# return None
|
|
||||||
|
|
||||||
# def extract_type(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# ArrayType = self.valobj.GetType().GetUnqualifiedType()
|
|
||||||
# if ArrayType.IsReferenceType():
|
|
||||||
# ArrayType = ArrayType.GetDereferencedType()
|
|
||||||
# elif ArrayType.IsPointerType():
|
|
||||||
# ArrayType = ArrayType.GetPointeeType()
|
|
||||||
# if ArrayType.GetNumberOfTemplateArguments() > 0:
|
|
||||||
# ElementType = ArrayType.GetTemplateArgumentType(0)
|
|
||||||
# else:
|
|
||||||
# ElementType = None
|
|
||||||
# return ElementType
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# self.Elements = self.valobj.GetChildMemberWithName('Elements')
|
|
||||||
# self.ElementsData = self.Elements.GetChildMemberWithName('Data')
|
|
||||||
# self.ArrayNum = self.ElementsData.GetChildMemberWithName('ArrayNum')
|
|
||||||
# self.NumFreeIndices = self.Elements.GetChildMemberWithName('NumFreeIndices')
|
|
||||||
# self.AllocationFlags = self.Elements.GetChildMemberWithName('AllocationFlags')
|
|
||||||
# self.AllocationFlagsAllocatorInstance = self.AllocationFlags.GetChildMemberWithName('AllocatorInstance')
|
|
||||||
# self.AllocatorInstance = self.ElementsData.GetChildMemberWithName('AllocatorInstance')
|
|
||||||
# self.AllocatorInstanceData = self.AllocatorInstance.GetChildMemberWithName('Data')
|
|
||||||
# self.AllocationFlagsInlineData = self.AllocationFlagsAllocatorInstance.GetChildMemberWithName('InlineData')
|
|
||||||
# self.AllocationFlagsInlineDataAddr = self.AllocationFlagsInlineData.AddressOf().GetValueAsUnsigned(0)
|
|
||||||
# self.AllocationFlagsSecondaryData = self.AllocationFlagsAllocatorInstance.GetChildMemberWithName('SecondaryData')
|
|
||||||
# self.AllocationFlagsSecondaryDataData = self.AllocationFlagsSecondaryData.GetChildMemberWithName('Data')
|
|
||||||
# self.SecondaryDataDataVal = self.AllocationFlagsSecondaryDataData.GetValueAsUnsigned(0)
|
|
||||||
# self.ElementType = self.extract_type()
|
|
||||||
# # This may fail due to C++ struct padding - will have to check
|
|
||||||
# self.ElementTypeSize = self.ElementType.GetByteSize() + self.TSetElement.GetValueAsUnsigned(0)
|
|
||||||
# assert self.ElementTypeSize != 0
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return True
|
|
||||||
|
|
||||||
# def UESetSummaryProvider(valobj,dict):
|
|
||||||
# return 'size=%s' % valobj.GetNumChildren()
|
|
||||||
|
|
||||||
# class UEMapSynthProvider:
|
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# # Can't cast to TSetElement - the template instantiation won't allow it
|
|
||||||
# Expr = '(size_t)sizeof(FSetElementId) + sizeof(int32)'
|
|
||||||
# self.TSetElement = self.valobj.CreateValueFromExpression('TSetElement', Expr)
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# ArrayNumVal = self.ArrayNum.GetValueAsUnsigned(0)
|
|
||||||
# NumFreeIndicesVal = self.NumFreeIndices.GetValueAsUnsigned(0)
|
|
||||||
# return ArrayNumVal - NumFreeIndicesVal;
|
|
||||||
# except:
|
|
||||||
# return 0;
|
|
||||||
|
|
||||||
# def get_child_index(self,name):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# return int(name.lstrip('[').rstrip(']'))
|
|
||||||
# except:
|
|
||||||
# return 0
|
|
||||||
|
|
||||||
# def get_child_at_index(self,index):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# logger >> "Retrieving child %s" % index
|
|
||||||
# if index < 0:
|
|
||||||
# return None;
|
|
||||||
|
|
||||||
# if index >= self.num_children():
|
|
||||||
# return None;
|
|
||||||
# try:
|
|
||||||
# offset = index * self.ElementTypeSize
|
|
||||||
# HasObject = 0
|
|
||||||
# if self.SecondaryDataDataVal != 0:
|
|
||||||
# Expr = '(bool)((((unsigned int*)%s)[%s/32] >> %s) & 1)' % (self.SecondaryDataDataVal, index, index)
|
|
||||||
# HasObject = 1 ##self.AllocationFlagsSecondaryDataData.CreateValueFromExpression('[%s]' % index, Expr).GetValueAsUnsigned(0)
|
|
||||||
# else:
|
|
||||||
# Expr = '(bool)((((unsigned int*)%s)[%s/32] >> %s) & 1)' % (self.AllocationFlagsInlineDataAddr, index, index)
|
|
||||||
# HasObject = 1 ##self.AllocationFlagsInlineData.CreateValueFromExpression('[%s]' % index, Expr).GetValueAsUnsigned(0)
|
|
||||||
|
|
||||||
# if HasObject == 1:
|
|
||||||
# return self.AllocatorInstanceData.CreateChildAtOffset('[%s]' % index,offset,self.ElementType)
|
|
||||||
# else:
|
|
||||||
# return self.valobj.CreateValueFromExpression('[%s]' % index, '(void*)0xDEADBEEF')
|
|
||||||
# except:
|
|
||||||
# return None
|
|
||||||
|
|
||||||
# def extract_type(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# ArrayType = self.Pairs.GetType().GetUnqualifiedType()
|
|
||||||
# if ArrayType.IsReferenceType():
|
|
||||||
# ArrayType = ArrayType.GetDereferencedType()
|
|
||||||
# elif ArrayType.IsPointerType():
|
|
||||||
# ArrayType = ArrayType.GetPointeeType()
|
|
||||||
# if ArrayType.GetNumberOfTemplateArguments() > 0:
|
|
||||||
# ElementType = ArrayType.GetTemplateArgumentType(0)
|
|
||||||
# else:
|
|
||||||
# ElementType = None
|
|
||||||
# return ElementType
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# logger = lldb.formatters.Logger.Logger()
|
|
||||||
# try:
|
|
||||||
# self.Pairs = self.valobj.GetChildMemberWithName('Pairs')
|
|
||||||
# self.Elements = self.Pairs.GetChildMemberWithName('Elements')
|
|
||||||
# self.ElementsData = self.Elements.GetChildMemberWithName('Data')
|
|
||||||
# self.ArrayNum = self.ElementsData.GetChildMemberWithName('ArrayNum')
|
|
||||||
# self.NumFreeIndices = self.Elements.GetChildMemberWithName('NumFreeIndices')
|
|
||||||
# self.AllocationFlags = self.Elements.GetChildMemberWithName('AllocationFlags')
|
|
||||||
# self.AllocationFlagsAllocatorInstance = self.AllocationFlags.GetChildMemberWithName('AllocatorInstance')
|
|
||||||
# self.AllocatorInstance = self.ElementsData.GetChildMemberWithName('AllocatorInstance')
|
|
||||||
# self.AllocatorInstanceData = self.AllocatorInstance.GetChildMemberWithName('Data')
|
|
||||||
# self.AllocationFlagsInlineData = self.AllocationFlagsAllocatorInstance.GetChildMemberWithName('InlineData')
|
|
||||||
# self.AllocationFlagsInlineDataAddr = self.AllocationFlagsInlineData.AddressOf().GetValueAsUnsigned(0)
|
|
||||||
# self.AllocationFlagsSecondaryData = self.AllocationFlagsAllocatorInstance.GetChildMemberWithName('SecondaryData')
|
|
||||||
# self.AllocationFlagsSecondaryDataData = self.AllocationFlagsSecondaryData.GetChildMemberWithName('Data')
|
|
||||||
# self.SecondaryDataDataVal = self.AllocationFlagsSecondaryDataData.GetValueAsUnsigned(0)
|
|
||||||
# self.ElementType = self.extract_type()
|
|
||||||
# # This may fail due to C++ struct padding - will have to check
|
|
||||||
# self.ElementTypeSize = self.ElementType.GetByteSize() + self.TSetElement.GetValueAsUnsigned(0)
|
|
||||||
# assert self.ElementTypeSize != 0
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return True
|
|
||||||
|
|
||||||
# def UEMapSummaryProvider(valobj,dict):
|
|
||||||
# return 'size=%s' % valobj.GetNumChildren()
|
|
||||||
|
|
||||||
# class UETObjectPtrSynthProvider:
|
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# return self.target.GetNumChildren() if self.resolved else 0
|
|
||||||
|
|
||||||
# def get_child_index(self, name):
|
|
||||||
# if not self.resolved:
|
|
||||||
# return None
|
|
||||||
# return self.target.GetIndexOfChildWithName(name)
|
|
||||||
|
|
||||||
# def get_child_at_index(self, index):
|
|
||||||
# if not self.resolved:
|
|
||||||
# return None
|
|
||||||
# return self.target.GetChildAtIndex(index)
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# try:
|
|
||||||
# self.DebugPtr = self.valobj.GetChildMemberWithName('DebugPtr')
|
|
||||||
# addr = self.DebugPtr.GetValueAsUnsigned(0)
|
|
||||||
# self.resolved = addr != 0 and (addr & 1) == 0
|
|
||||||
# self.target = self.DebugPtr.Dereference() if self.resolved else None
|
|
||||||
# except:
|
|
||||||
# self.resolved = False
|
|
||||||
# self.target = None
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return self.resolved and self.target.GetNumChildren() > 0
|
|
||||||
|
|
||||||
# def UETObjectPtrSummaryProvider(valobj, dict):
|
|
||||||
# raw = valobj.GetNonSyntheticValue()
|
|
||||||
# DebugPtr = raw.GetChildMemberWithName('DebugPtr')
|
|
||||||
# addr = DebugPtr.GetValueAsUnsigned(0)
|
|
||||||
# if addr == 0:
|
|
||||||
# return 'nullptr'
|
|
||||||
# if addr & 1:
|
|
||||||
# return 'unresolved'
|
|
||||||
# return DebugPtr.Dereference().GetSummary() or ('0x%x' % addr)
|
|
||||||
|
|
||||||
# class UETSharedPtrSynthProvider:
|
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# return self.target.GetNumChildren() if self.valid else 0
|
|
||||||
|
|
||||||
# def get_child_index(self, name):
|
|
||||||
# if not self.valid:
|
|
||||||
# return None
|
|
||||||
# return self.target.GetIndexOfChildWithName(name)
|
|
||||||
|
|
||||||
# def get_child_at_index(self, index):
|
|
||||||
# if not self.valid:
|
|
||||||
# return None
|
|
||||||
# return self.target.GetChildAtIndex(index)
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# try:
|
|
||||||
# self.Object = self.valobj.GetChildMemberWithName('Object')
|
|
||||||
# addr = self.Object.GetValueAsUnsigned(0)
|
|
||||||
# self.valid = addr != 0
|
|
||||||
# self.target = self.Object.Dereference() if self.valid else None
|
|
||||||
# except:
|
|
||||||
# self.valid = False
|
|
||||||
# self.target = None
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return self.valid and self.target.GetNumChildren() > 0
|
|
||||||
|
|
||||||
# def UETSharedPtrSummaryProvider(valobj, dict):
|
|
||||||
# raw = valobj.GetNonSyntheticValue()
|
|
||||||
# Object = raw.GetChildMemberWithName('Object')
|
|
||||||
# addr = Object.GetValueAsUnsigned(0)
|
|
||||||
# if addr == 0:
|
|
||||||
# return 'nullptr'
|
|
||||||
# return Object.Dereference().GetSummary() or ('0x%x' % addr)
|
|
||||||
|
|
||||||
# def _tweakptr_alive(raw):
|
|
||||||
# """True if a TWeakPtr's referenced object is still alive.
|
|
||||||
|
|
||||||
# Walks WeakReferenceCount -> ReferenceController -> SharedReferenceCount.
|
|
||||||
# SharedReferenceCount may be std::atomic<int32>, in which case we drill into
|
|
||||||
# the atomic's inner storage.
|
|
||||||
# """
|
|
||||||
# wrc = raw.GetChildMemberWithName('WeakReferenceCount')
|
|
||||||
# rc = wrc.GetChildMemberWithName('ReferenceController')
|
|
||||||
# if rc.GetValueAsUnsigned(0) == 0:
|
|
||||||
# return False
|
|
||||||
# src = rc.Dereference().GetChildMemberWithName('SharedReferenceCount')
|
|
||||||
# if not src.IsValid():
|
|
||||||
# return False
|
|
||||||
# count = src.GetValueAsSigned(-1)
|
|
||||||
# # std::atomic<int32> has no direct value; drill into its inner storage
|
|
||||||
# while count == -1 and src.GetNumChildren() > 0:
|
|
||||||
# src = src.GetChildAtIndex(0)
|
|
||||||
# count = src.GetValueAsSigned(-1)
|
|
||||||
# return count > 0
|
|
||||||
|
|
||||||
# class UETWeakPtrSynthProvider:
|
|
||||||
|
|
||||||
# def __init__(self, valobj, dict):
|
|
||||||
# self.valobj = valobj
|
|
||||||
|
|
||||||
# def num_children(self):
|
|
||||||
# return self.target.GetNumChildren() if self.alive else 0
|
|
||||||
|
|
||||||
# def get_child_index(self, name):
|
|
||||||
# if not self.alive:
|
|
||||||
# return None
|
|
||||||
# return self.target.GetIndexOfChildWithName(name)
|
|
||||||
|
|
||||||
# def get_child_at_index(self, index):
|
|
||||||
# if not self.alive:
|
|
||||||
# return None
|
|
||||||
# return self.target.GetChildAtIndex(index)
|
|
||||||
|
|
||||||
# def update(self):
|
|
||||||
# try:
|
|
||||||
# self.Object = self.valobj.GetChildMemberWithName('Object')
|
|
||||||
# self.alive = self.Object.GetValueAsUnsigned(0) != 0 and _tweakptr_alive(self.valobj)
|
|
||||||
# self.target = self.Object.Dereference() if self.alive else None
|
|
||||||
# except:
|
|
||||||
# self.alive = False
|
|
||||||
# self.target = None
|
|
||||||
|
|
||||||
# def has_children(self):
|
|
||||||
# return self.alive and self.target.GetNumChildren() > 0
|
|
||||||
|
|
||||||
# def UETWeakPtrSummaryProvider(valobj, dict):
|
|
||||||
# raw = valobj.GetNonSyntheticValue()
|
|
||||||
# Object = raw.GetChildMemberWithName('Object')
|
|
||||||
# addr = Object.GetValueAsUnsigned(0)
|
|
||||||
# if addr == 0:
|
|
||||||
# return 'nullptr'
|
|
||||||
# if not _tweakptr_alive(raw):
|
|
||||||
# return 'expired'
|
|
||||||
# return Object.Dereference().GetSummary() or ('0x%x' % addr)
|
|
||||||
|
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
#
|
#
|
||||||
@@ -1040,38 +590,48 @@ lldb.SBValue.__repr__ = _sbvalue_repr
|
|||||||
#
|
#
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
|
def _register_provider(cat, pattern, summary_fn=None, synth_cls=None):
|
||||||
|
"""Register summary and/or synthetic providers for a type pattern."""
|
||||||
|
spec = lldb.SBTypeNameSpecifier(pattern, lldb.eFormatterMatchRegex)
|
||||||
|
if summary_fn:
|
||||||
|
cat.AddTypeSummary(spec, lldb.SBTypeSummary.CreateWithFunctionName(
|
||||||
|
__name__ + '.' + summary_fn, lldb.eTypeOptionCascade))
|
||||||
|
if synth_cls:
|
||||||
|
cat.AddTypeSynthetic(spec, lldb.SBTypeSynthetic.CreateWithClassName(
|
||||||
|
__name__ + '.' + synth_cls, lldb.eTypeOptionCascade))
|
||||||
|
|
||||||
def __lldb_init_module(debugger, dict):
|
def __lldb_init_module(debugger, dict):
|
||||||
print("Running lldb_init_module")
|
print("Running lldb_init_module")
|
||||||
_init_globals(debugger.GetSelectedTarget())
|
_init_globals(debugger.GetSelectedTarget())
|
||||||
debugger.HandleCommand('type category delete UEDataFormatters')
|
debugger.HandleCommand('type category delete ' + __name__)
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UEFStringSummaryProvider -e FString -w UEDataFormatters')
|
cat = debugger.CreateCategory(__name__)
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UEFNameSummaryProvider -e FName -w UEDataFormatters')
|
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TObjectPtrSynthProvider -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^FString$', summary_fn='UEFStringSummaryProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TObjectPtrSummaryProvider -e -x "^TObjectPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^FName$', summary_fn='UEFNameSummaryProvider')
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TStrongObjectPtrSynthProvider -x "^TStrongObjectPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TObjectPtr<.+>$', summary_fn='TObjectPtrSummaryProvider', synth_cls='TObjectPtrSynthProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TStrongObjectPtrSummaryProvider -e -x "^TStrongObjectPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TStrongObjectPtr<.+>$', summary_fn='TStrongObjectPtrSummaryProvider', synth_cls='TStrongObjectPtrSynthProvider')
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TSharedPtrSynthProvider -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TSharedPtr<.+>$', summary_fn='TSharedPtrSummaryProvider', synth_cls='TSharedPtrSynthProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TSharedPtrSummaryProvider -e -x "^TSharedPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TSharedRef<.+>$', summary_fn='TSharedPtrSummaryProvider', synth_cls='TSharedPtrSynthProvider')
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TSharedPtrSynthProvider -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TWeakPtr<.+>$', summary_fn='TWeakPtrSummaryProvider', synth_cls='TWeakPtrSynthProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TSharedPtrSummaryProvider -e -x "^TSharedRef<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TWeakObjectPtr<.+>$', summary_fn='TWeakObjectPtrSummaryProvider', synth_cls='TWeakObjectPtrSynthProvider')
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakPtrSynthProvider -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^FWeakObjectPtr$', summary_fn='TWeakObjectPtrSummaryProvider', synth_cls='TWeakObjectPtrSynthProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakPtrSummaryProvider -e -x "^TWeakPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TArray<.+>$', summary_fn='TArraySummaryProvider', synth_cls='TArraySynthProvider')
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakObjectPtrSynthProvider -x "^TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TBitArray<.+>$', summary_fn='TBitArraySummaryProvider', synth_cls='TBitArraySynthProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakObjectPtrSummaryProvider -e -x "^TWeakObjectPtr<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^TSparseArray<.+>$', summary_fn='TSparseArraySummaryProvider', synth_cls='TSparseArraySynthProvider')
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.TWeakObjectPtrSynthProvider -x "^FWeakObjectPtr$" -w UEDataFormatters')
|
_register_provider(cat, '^UObject$', summary_fn='UObjectSummaryProvider', synth_cls='UObjectSynthProvider')
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.TWeakObjectPtrSummaryProvider -e FWeakObjectPtr -w UEDataFormatters')
|
|
||||||
debugger.HandleCommand('type synthetic add -l UEDataFormatter.UObjectSynthProvider UObject -w UEDataFormatters')
|
for class_name in (
|
||||||
debugger.HandleCommand('type summary add -F UEDataFormatter.UObjectSummaryProvider -e UObject -w UEDataFormatters')
|
'AActor', 'APawn', 'ACharacter', 'APlayerController', 'AGameModeBase',
|
||||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEArraySynthProvider -x "TArray<.+,.+>$" -w UEDataFormatters')
|
'UActorComponent', 'USceneComponent', 'UPrimitiveComponent',
|
||||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEArraySummaryProvider -e -x "TArray<.+>$" -w UEDataFormatters')
|
'UWidget', 'UUserWidget', 'UWorld', 'ULevel', 'UGameInstance'):
|
||||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEBitArraySynthProvider -x "TBitArray<.+>$" -w UEDataFormatters')
|
_register_provider(cat, '^%s$' % class_name, summary_fn='UObjectSummaryProvider')
|
||||||
# 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')
|
cat.SetEnabled(True)
|
||||||
# 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')
|
def counttypes():
|
||||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UESetSummaryProvider -e -x "TSet<.+>$" -w UEDataFormatters')
|
# Count all class types.
|
||||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEMapSynthProvider -x "TMap<.+>$" -w UEDataFormatters')
|
target = lldb.debugger.GetSelectedTarget()
|
||||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEMapSummaryProvider -e -x "TMap<.+>$" -w UEDataFormatters')
|
count = 0
|
||||||
# debugger.HandleCommand('type synthetic add -l UEDataFormatter.UEMapSynthProvider -x "TMapBase<.+>$" -w UEDataFormatters')
|
for module in target.module_iter():
|
||||||
# debugger.HandleCommand('type summary add -F UEDataFormatter.UEMapSummaryProvider -e -x "TMapBase<.+>$" -w UEDataFormatters')
|
count += module.GetTypes(lldb.eTypeClassClass).GetSize()
|
||||||
debugger.HandleCommand("type category enable UEDataFormatters")
|
print('UEDataFormatter: %d class types found' % count)
|
||||||
|
|||||||
Reference in New Issue
Block a user