Skip to content

Commit

Permalink
Merge pull request #235 from facebook/heapfrom
Browse files Browse the repository at this point in the history
Add heapfrom command
  • Loading branch information
kastiglione committed Mar 12, 2018
2 parents cd4582c + ff3c252 commit fa0d4e7
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions commands/FBDebugCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def lldbcommands():
FBFindInstancesCommand(),
FBMethodBreakpointEnableCommand(),
FBMethodBreakpointDisableCommand(),
FBHeapFromCommand(),
FBSequenceCommand(),
]

Expand Down Expand Up @@ -380,6 +381,52 @@ def chiselLibraryPath(self):
return os.path.join(source_dir, '..', '..', 'lib', 'Chisel.framework', 'Chisel')


class FBHeapFromCommand(fb.FBCommand):
def name(self):
return 'heapfrom'

def description(self):
return 'Show all nested heap pointers contained within a given variable.'

def run(self, arguments, options):
# This command is like `expression --synthetic-type false`, except only showing nested heap references.
var = self.context.frame.var(arguments[0])
if not var or not var.IsValid():
self.result.SetError('No variable named "{}"'.format(arguments[0]))
return

# Use the actual underlying structure of the variable, not the human friendly (synthetic) one.
root = var.GetNonSyntheticValue()

# Traversal of SBValue tree to get leaf nodes, which is where heap pointers will be.
leafs = []
queue = [root]
while queue:
node = queue.pop(0)
if node.num_children == 0:
leafs.append(node)
else:
queue += [node.GetChildAtIndex(i) for i in range(node.num_children)]

pointers = {}
for node in leafs:
# Assumption: an addr that has no value means a pointer.
if node.addr and not node.value:
pointers[node.load_addr] = node.path

options = lldb.SBExpressionOptions()
options.SetLanguage(lldb.eLanguageTypeC)
def isHeap(addr):
lookup = '(int)malloc_size({})'.format(addr)
return self.context.frame.EvaluateExpression(lookup, options).unsigned != 0

allocations = (addr for addr in pointers if isHeap(addr))
for addr in allocations:
print >>self.result, '0x{addr:x} {path}'.format(addr=addr, path=pointers[addr])
if not allocations:
print >>self.result, "No heap addresses found"


class FBSequenceCommand(fb.FBCommand):
def name(self):
return 'sequence'
Expand Down

0 comments on commit fa0d4e7

Please sign in to comment.