Skip to content

Instantly share code, notes, and snippets.

@v0lat1le
Created October 27, 2017 03:04
Show Gist options
  • Save v0lat1le/f1b6b350b81a6e56d3eee0215642aec9 to your computer and use it in GitHub Desktop.
Save v0lat1le/f1b6b350b81a6e56d3eee0215642aec9 to your computer and use it in GitHub Desktop.
LLDB boost::variant data formatter
import lldb
import lldb.formatters.Logger
def templateParams(s):
depth = 0
start = s.find('<') + 1
result = []
for i, c in enumerate(s[start:], start):
if c == '<':
depth += 1
elif c == '>':
if depth == 0:
result.append(s[start: i].strip())
break
depth -= 1
elif c == ',' and depth == 0:
result.append(s[start: i].strip())
start = i+1
return result
def BoostVariantSummary(valobj, internal_dict):
tps = templateParams(valobj.type.GetCanonicalType().name)
return 'variant<' + tps[valobj.GetChildMemberWithName('which_').signed] + '>'
class BoostVariantSyntheticChildrenProvider:
nodeNames = ['value']
def __init__(self, valobj, internal_dict):
self.valobj = valobj
self.typeParams = templateParams(valobj.type.GetCanonicalType().name)
def num_children(self):
return len(self.nodeNames)
def has_children(self):
return True
def get_child_index(self, name):
try:
return self.nodeNames.index(name)
except ValueError:
return None
def get_child_at_index(self, index):
logger = lldb.formatters.Logger.Logger()
logger >> "Retrieving child " + str(index)
try:
node = self.nodeNames[index]
except IndexError:
return None
which_ = self.valobj.GetChildMemberWithName('which_').signed
logger >> "which " + str(which_)
try:
valueTypeName = self.typeParams[which_]
except IndexError:
return self.valobj.CreateValueFromExpression(node, '(const char*)"unknown"')
logger >> "type " + valueTypeName
if node == 'type':
if valueTypeName.startswith("boost::recursive_wrapper"):
valueTypeName = templateParams(valueTypeName)[0]
return self.valobj.CreateValueFromExpression(node, '(const char*)"' + valueTypeName + '"')
if node == 'value':
valueType = lldb.target.FindFirstType(valueTypeName)
value = self.valobj.GetChildMemberWithName('storage_').Cast(valueType)
if valueTypeName.startswith("boost::recursive_wrapper"):
value = value.GetChildMemberWithName('p_').Dereference()
valueType = value.type
return self.valobj.CreateValueFromData(node, value.GetData(), valueType)
return None
def update(self):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment