Skip to content

Commit

Permalink
Merge pull request mmp#339 from wuyakuma/master
Browse files Browse the repository at this point in the history
LLDB DataFormatters (Debug Visualizer)
  • Loading branch information
mmp authored Apr 29, 2023
2 parents 11be252 + d25f567 commit 1ed5139
Showing 1 changed file with 268 additions and 0 deletions.
268 changes: 268 additions & 0 deletions src/pbrt/pbrt_lldbdataformatters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
"""
LLDB Formatters
1. Load Manually (everytime)
use lldb command 'command script import [PATH]/pbrt_lldbdataformatters.py' (without the quotes)
2. Load Automatically (add to ~/.lldbinit)
1) create ~/.lldbinit file if there isn't
2) open ~/.lldbinit
3) add 'command script import [PATH]/pbrt_lldbdataformatters.py' to the file (without the quotes)
4) restart xcode
"""

import lldb;
import lldb.formatters.Logger;

# Uncomment this to debug
# lldb.formatters.Logger._lldb_formatters_debug_level=1

# TaggedPointer
# seems GetTemplateArgumentType() does work with Variadic Templates, have to parse them into list
class TaggedPointerSynthProvider:
def __init__(self, valobj, dirt):
logger = lldb.formatters.Logger.Logger()
self.valobj = valobj
typeName=self.valobj.GetTypeName()
leftBracket = typeName.find('<')
rightBracket = typeName.find('>')
packedTypes = typeName[leftBracket+1:rightBracket]
logger >> "PackedType: " + str(packedTypes)
self.type_strings = packedTypes.split(',')
logger >> "PackedTypeList: " + str(self.type_strings)
self.update()

def has_children(self):
return True

def num_children(self):
return 2

def get_child_index(self, name):
try:
return int(name.lstrip('[').rstrip(']'))
except:
return -1

def get_child_at_index(self, index):
logger = lldb.formatters.Logger.Logger()
if index == 0:
return self.valobj.CreateValueFromExpression('tag', str(self.tag))
if index == 1:
if self.tag > 0:
expr = '(' + self.type + '*)' + str(self.ptr)
logger >> 'expr ' + expr
return self.valobj.CreateValueFromExpression('ptr', expr)
else:
return self.valobj.CreateValueFromExpression('ptr', 'null')
return None

def update(self):
bits = self.valobj.GetChildMemberWithName('bits').GetValueAsUnsigned()
self.tag = (bits & 0xFE00000000000000) >> 57
if self.tag > 0 and self.tag <= len(self.type_strings):
self.type = self.type_strings[self.tag-1]
else:
self.type = 'void'
self.ptr = (bits& 0x01FFFFFFFFFFFFFF)

# Optional
class OptionalSynthProvider:
def __init__(self, valobj, dirt):
self.valobj = valobj
self.update()

def has_children(self):
return self.set.GetValueAsUnsigned() != 0

def num_children(self):
if self.set.GetValueAsUnsigned() == 0:
return 0
else:
return 1

def get_child_index(self, name):
try:
return int(name.lstrip('[').rstrip(']'))
except:
return -1

def get_child_at_index(self, index):
if index == 0:
expr = '*(' + self.type.GetName() + '*)' + str(self.ptr.GetValueAsUnsigned())
return self.valobj.CreateValueFromExpression('ptr', str(expr))
return None

def update(self):
try:
self.set = self.valobj.GetChildMemberWithName('set')
self.type = self.extract_type()
self.ptr = self.valobj.GetChildMemberWithName('optionalValue').AddressOf()
except:
pass

def extract_type(self):
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 OptionalSummaryProvider(valobj, internal_dict):
set = valobj.GetNumChildren()
if set:
return 'set'
return 'null'


# Span
class SpanSynthProvider:
def __init__(self, valobj, dirt):
self.valobj = valobj
self.update()

def has_children(self):
return True

def num_children(self):
return self.size

def get_child_index(self, name):
try:
return int(name.lstrip('[').rstrip(']'))
except:
return -1

def get_child_at_index(self, index):
if index < 0:
return None
if index >= self.num_children():
return None
offset = index * self.type_size
return self.ptr.CreateChildAtOffset('['+str(index)+']', offset, self.date_type)

def update(self):
self.size = self.valobj.GetChildMemberWithName('n').GetValueAsUnsigned()
self.ptr = self.valobj.GetChildMemberWithName('ptr')
valType = self.valobj.GetType()
if valType.IsReferenceType():
valType = valType.GetDereferencedType()
self.date_type = valType.GetTemplateArgumentType(0)
self.type_size = self.date_type.GetByteSize()

def SpanSummaryProvider(valobj, internal_dict):
length = valobj.GetNumChildren()
return 'size = %d' % length


# Array
class ArraySynthProvider:
def __init__(self, valobj, dirt):
self.valobj = valobj
self.update()

def has_children(self):
return True

def num_children(self):
return self.size

def get_child_index(self, name):
try:
return int(name.lstrip('[').rstrip(']'))
except:
return -1

def get_child_at_index(self, index):
if index < 0:
return None
if index >= self.num_children():
return None
if self.data_type == None:
return None
offset = index * self.type_size
return self.values.CreateChildAtOffset('['+str(index)+']', offset, self.data_type)

def update(self):
try:
self.values = self.valobj.GetChildMemberWithName('values')
valType = self.values.GetType()
if valType.IsReferenceType():
valType = valType.GetDereferencedType()
if valType.IsArrayType():
arraySize = valType.GetByteSize()
self.data_type = valType.GetArrayElementType()
self.type_size = self.data_type.GetByteSize()
self.size = arraySize/self.type_size
else:
self.data_type = None
self.type_size = 0
self.size = 0
except:
pass

def ArraySummaryProvider(valobj, internal_dict):
length = valobj.GetNumChildren()
return 'size = %d' % length

# Vector
class VectorSynthProvider:
def __init__(self, valobj, dirt):
self.valobj = valobj
self.update()

def has_children(self):
return True

def num_children(self):
return self.size.GetValueAsUnsigned()

def get_child_index(self, name):
try:
return int(name.lstrip('[').rstrip(']'))
except:
return -1

def get_child_at_index(self, index):
if index < 0:
return None
if index >= self.num_children():
return None
if self.data_type == None:
return None
offset = index * self.type_size
return self.ptr.CreateChildAtOffset('['+str(index)+']', offset, self.data_type)

def update(self):
try:
self.size = self.valobj.GetChildMemberWithName('nStored')
self.capacity = self.valobj.GetChildMemberWithName('nAlloc')
self.ptr = self.valobj.GetChildMemberWithName('ptr')
self.data_type = self.ptr.GetType()
if self.data_type.IsPointerType():
self.data_type = self.data_type.GetPointeeType()
self.type_size = self.data_type.GetByteSize()
except:
pass

def VectorSummaryProvider(valobj, internal_dict):
length = valobj.GetNumChildren()
return 'size = %d' % length


def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('type synthetic add -l pbrt_lldbdataformatters.TaggedPointerSynthProvider -x "^pbrt::TaggedPointer<.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type synthetic add -l pbrt_lldbdataformatters.OptionalSynthProvider -x "^pstd::optional<.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type summary add -F pbrt_lldbdataformatters.OptionalSummaryProvider -e -x "^pstd::optional<.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type synthetic add -l pbrt_lldbdataformatters.SpanSynthProvider -x "^pstd::span<.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type summary add -F pbrt_lldbdataformatters.SpanSummaryProvider -e -x "^pstd::span<.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type synthetic add -l pbrt_lldbdataformatters.ArraySynthProvider -x "^pstd::array<.+,.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type summary add -F pbrt_lldbdataformatters.ArraySummaryProvider -e -x "^pstd::array<.+,.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type synthetic add -l pbrt_lldbdataformatters.VectorSynthProvider -x "^pstd::vector<.+,.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand('type summary add -F pbrt_lldbdataformatters.VectorSummaryProvider -e -x "^pstd::vector<.+,.+>$" -w pbrt_lldbdataformatters')
debugger.HandleCommand("type category enable pbrt_lldbdataformatters")

0 comments on commit 1ed5139

Please sign in to comment.