Created
October 27, 2017 03:04
-
-
Save v0lat1le/f1b6b350b81a6e56d3eee0215642aec9 to your computer and use it in GitHub Desktop.
LLDB boost::variant data formatter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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