Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions commands/FBAutoLayoutCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ def run(self, arguments, options):
def setBorderOnAmbiguousViewRecursive(view, width, color):
if not fb.evaluateBooleanExpression('[(id)%s isKindOfClass:(Class)[UIView class]]' % view):
return

isAmbiguous = fb.evaluateBooleanExpression('(BOOL)[%s hasAmbiguousLayout]' % view)
if isAmbiguous:
layer = viewHelpers.convertToLayer(view)
lldb.debugger.HandleCommand('expr (void)[%s setBorderWidth:(CGFloat)%s]' % (layer, width))
lldb.debugger.HandleCommand('expr (void)[%s setBorderColor:(CGColorRef)[(id)[UIColor %sColor] CGColor]]' % (layer, color))

subviews = fb.evaluateExpression('(id)[%s subviews]' % view)
subviewsCount = int(fb.evaluateExpression('(int)[(id)%s count]' % subviews))
if subviewsCount > 0:
Expand Down
4 changes: 2 additions & 2 deletions commands/FBDebugCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ def run(self, arguments, options):

objectAddress = int(fb.evaluateObjectExpression(commandForObject), 0)

ivarOffsetCommand = '(ptrdiff_t)ivar_getOffset((Ivar)object_getInstanceVariable((id){}, "{}", 0))'.format(objectAddress, ivarName)
ivarOffsetCommand = '(ptrdiff_t)ivar_getOffset((void*)object_getInstanceVariable((id){}, "{}", 0))'.format(objectAddress, ivarName)
ivarOffset = fb.evaluateIntegerExpression(ivarOffsetCommand)

# A multi-statement command allows for variables scoped to the command, not permanent in the session like $variables.
ivarSizeCommand = ('unsigned int size = 0;'
'char *typeEncoding = (char *)ivar_getTypeEncoding((Ivar)class_getInstanceVariable((Class)object_getClass((id){}), "{}"));'
'char *typeEncoding = (char *)ivar_getTypeEncoding((void*)class_getInstanceVariable((Class)object_getClass((id){}), "{}"));'
'(char *)NSGetSizeAndAlignment(typeEncoding, &size, 0);'
'size').format(objectAddress, ivarName)
ivarSize = int(fb.evaluateExpression(ivarSizeCommand), 0)
Expand Down
4 changes: 2 additions & 2 deletions commands/FBDisplayCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ def options(self):
def run(self, args, options):
colorClassName = 'UIColor'
isMac = runtimeHelpers.isMacintoshArch()

if isMac:
colorClassName = 'NSColor'

layer = viewHelpers.convertToLayer(args[0])
lldb.debugger.HandleCommand('expr (void)[%s setBorderWidth:(CGFloat)%s]' % (layer, options.width))
lldb.debugger.HandleCommand('expr (void)[%s setBorderColor:(CGColorRef)[(id)[%s %sColor] CGColor]]' % (layer, colorClassName, options.color))
Expand Down
4 changes: 2 additions & 2 deletions commands/FBFindCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def printMatchesInViewOutputStringAndCopyFirstToClipboard(needle, haystack):
view = match.groups()[-1]
className = fb.evaluateExpressionValue('(id)[(' + view + ') class]').GetObjectDescription()
print('{} {}'.format(view, className))
if first == None:
if first is None:
first = view
cmd = 'echo %s | tr -d "\n" | pbcopy' % view
os.system(cmd)
Expand All @@ -125,7 +125,7 @@ def run(self, arguments, options):
if re.match(r'.*' + needle + '.*', a11yLabel, re.IGNORECASE):
print('{} {}'.format(view, a11yLabel))

if first == None:
if first is None:
first = view
cmd = 'echo %s | tr -d "\n" | pbcopy' % first
os.system(cmd)
Expand Down
4 changes: 2 additions & 2 deletions commands/FBFlickerCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ def inputCallback(self, input):
elif input == 'p':
recusionName = 'recursiveDescription'
isMac = runtimeHelpers.isMacintoshArch()

if isMac:
recursionName = '_subtreeDescription'

lldb.debugger.HandleCommand('po [(id)' + oldView + ' ' + recusionName + ']')
else:
print '\nI really have no idea what you meant by \'' + input + '\'... =\\\n'
Expand Down
48 changes: 24 additions & 24 deletions commands/FBInvocationCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def stackStartAddressInSelectedFrame(frame):
return int(frame.EvaluateExpression('($esp + 8)').GetValue())
else:
return int(frame.EvaluateExpression('($ebp + 8)').GetValue())


def findArgAtIndexFromStackFrame(frame, index):
return fb.evaluateExpression('*(int *)' + str(findArgAdressAtIndexFromStackFrame(frame, index)))
Expand Down Expand Up @@ -134,36 +134,36 @@ def prettyPrintInvocation(frame, invocation):
print readableString
else:
if encoding[0] == '{':
encoding = encoding[1:len(encoding)-1]
encoding = encoding[1:]
print (hex(address) + ', address of ' + encoding + ' ' + description).strip()

index += 1

def argumentAsString(frame, address, encoding):
if encoding[0] == '{':
encoding = encoding[1:len(encoding)-1]
encoding = encoding[1:]

encodingMap = {
'c' : 'char',
'i' : 'int',
's' : 'short',
'l' : 'long',
'q' : 'long long',

'C' : 'unsigned char',
'I' : 'unsigned int',
'S' : 'unsigned short',
'L' : 'unsigned long',
'Q' : 'unsigned long long',

'f' : 'float',
'd' : 'double',
'B' : 'bool',
'v' : 'void',
'*' : 'char *',
'@' : 'id',
'#' : 'Class',
':' : 'SEL',
'c': 'char',
'i': 'int',
's': 'short',
'l': 'long',
'q': 'long long',

'C': 'unsigned char',
'I': 'unsigned int',
'S': 'unsigned short',
'L': 'unsigned long',
'Q': 'unsigned long long',

'f': 'float',
'd': 'double',
'B': 'bool',
'v': 'void',
'*': 'char *',
'@': 'id',
'#': 'Class',
':': 'SEL',
}

pointers = ''
Expand Down Expand Up @@ -202,5 +202,5 @@ def argumentAsString(frame, address, encoding):
description = value.GetSummary()
if description:
return type + ': ' + description

return None
20 changes: 10 additions & 10 deletions commands/FBPrintCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ def args(self):
def run(self, arguments, options):
maxDepth = int(options.depth)
isMac = runtimeHelpers.isMacintoshArch()
if (arguments[0] == '__keyWindow_dynamic__'):

if arguments[0] == '__keyWindow_dynamic__':
arguments[0] = '(id)[[UIApplication sharedApplication] keyWindow]'

if isMac:
arguments[0] = '(id)[[[[NSApplication sharedApplication] windows] objectAtIndex:0] contentView]'

Expand All @@ -65,9 +65,9 @@ def run(self, arguments, options):
print 'Failed to walk view hierarchy. Make sure you pass a view, not any other kind of object or expression.'
else:
printingMethod = 'recursiveDescription'
if (isMac):
if isMac:
printingMethod = '_subtreeDescription'

description = fb.evaluateExpressionValue('(id)[' + arguments[0] + ' ' + printingMethod + ']').GetObjectDescription()
if maxDepth > 0:
separator = re.escape(" | ")
Expand Down Expand Up @@ -100,10 +100,10 @@ def args(self):

def run(self, arguments, options):
isMac = runtimeHelpers.isMacintoshArch()
if (arguments[0] == '__keyWindow_rootVC_dynamic__'):

if arguments[0] == '__keyWindow_rootVC_dynamic__':
arguments[0] = '(id)[(id)[[UIApplication sharedApplication] keyWindow] rootViewController]'
if (isMac):
if isMac:
arguments[0] = '(id)[[[[NSApplication sharedApplication] windows] objectAtIndex:0] contentViewController]'

print vcHelpers.viewControllerRecursiveDescription(arguments[0])
Expand All @@ -123,7 +123,7 @@ def run(self, arguments, options):
def _printIterative(initialValue, generator):
indent = 0
for currentValue in generator(initialValue):
print ' | '*indent + currentValue
print ' | ' * indent + currentValue
indent += 1


Expand Down Expand Up @@ -267,7 +267,7 @@ def run(self, arguments, options):
object = fb.evaluateObjectExpression(commandForObject)
objectClass = fb.evaluateExpressionValue('(id)[(' + object + ') class]').GetObjectDescription()

ivarTypeCommand = '((char *)ivar_getTypeEncoding((Ivar)object_getInstanceVariable((id){}, \"{}\", 0)))[0]'.format(object, ivarName)
ivarTypeCommand = '((char *)ivar_getTypeEncoding((void*)object_getInstanceVariable((id){}, \"{}\", 0)))[0]'.format(object, ivarName)
ivarTypeEncodingFirstChar = fb.evaluateExpression(ivarTypeCommand)

printCommand = 'po' if ('@' in ivarTypeEncodingFirstChar) else 'p'
Expand Down
34 changes: 17 additions & 17 deletions commands/FBVisualizationCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ def _showImage(commandForImage):
else:
raise

imageDataAddress = fb.evaluateObjectExpression('UIImagePNGRepresentation((id)' + commandForImage +')')
imageDataAddress = fb.evaluateObjectExpression('UIImagePNGRepresentation((id)' + commandForImage + ')')
imageBytesStartAddress = fb.evaluateExpression('(void *)[(id)' + imageDataAddress + ' bytes]')
imageBytesLength = fb.evaluateExpression('(NSUInteger)[(id)' + imageDataAddress + ' length]')

address = int(imageBytesStartAddress,16)
address = int(imageBytesStartAddress, 16)
length = int(imageBytesLength)

if not (address or length):
print 'Could not get image data.'
return

process = lldb.debugger.GetSelectedTarget().GetProcess()
error = lldb.SBError()
mem = process.ReadMemory(address, length, error)

if error is not None and str(error) != 'success':
print error
else:
Expand Down Expand Up @@ -76,35 +76,35 @@ def _dataIsImage(data):
data = '(' + data + ')'

frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
result = frame.EvaluateExpression('(id)[UIImage imageWithData:' + data + ']');
result = frame.EvaluateExpression('(id)[UIImage imageWithData:' + data + ']')

if result.GetError() is not None and str(result.GetError()) != 'success':
return 0;
return 0
else:
isImage = result.GetValueAsUnsigned() != 0;
isImage = result.GetValueAsUnsigned() != 0
if isImage:
return 1;
return 1
else:
return 0;
return 0

def _dataIsString(data):
data = '(' + data + ')'

frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
result = frame.EvaluateExpression('(NSString*)[[NSString alloc] initWithData:' + data + ' encoding:4]');
result = frame.EvaluateExpression('(NSString*)[[NSString alloc] initWithData:' + data + ' encoding:4]')

if result.GetError() is not None and str(result.GetError()) != 'success':
return 0;
return 0
else:
isString = result.GetValueAsUnsigned() != 0;
isString = result.GetValueAsUnsigned() != 0
if isString:
return 1;
return 1
else:
return 0;
return 0

def _visualize(target):
target = '(' + target + ')'

if fb.evaluateBooleanExpression('(unsigned long)CFGetTypeID((CFTypeRef)' + target + ') == (unsigned long)CGImageGetTypeID()'):
_showImage('(id)[UIImage imageWithCGImage:' + target + ']')
else:
Expand All @@ -116,11 +116,11 @@ def _visualize(target):
_showLayer(target)
elif objectHelpers.isKindOfClass(target, 'NSData'):
if _dataIsImage(target):
_showImage('(id)[UIImage imageWithData:' + target + ']');
_showImage('(id)[UIImage imageWithData:' + target + ']')
elif _dataIsString(target):
lldb.debugger.HandleCommand('po (NSString*)[[NSString alloc] initWithData:' + target + ' encoding:4]')
else:
print 'Data isn\'t an image and isn\'t a string.';
print 'Data isn\'t an image and isn\'t a string.'
else:
print '{} isn\'t supported. You can visualize UIImage, CGImageRef, UIView, CALayer or NSData.'.format(objectHelpers.className(target))

Expand Down
9 changes: 4 additions & 5 deletions fblldb.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def runCommand(debugger, input, result, dict):
# thing.
options = command.options()
if len(options) == 0:
if not '--' in splitInput:
if '--' not in splitInput:
splitInput.insert(0, '--')

parser = optionParserForCommand(command)
Expand All @@ -74,7 +74,7 @@ def runCommand(debugger, input, result, dict):
# the initial args form an expression and combine them into a single arg.
if len(args) > len(command.args()):
overhead = len(args) - len(command.args())
head = args[:overhead+1] # Take N+1 and reduce to 1.
head = args[:overhead + 1] # Take N+1 and reduce to 1.
args = [' '.join(head)] + args[-overhead:]

if validateArgsForCommand(args, command):
Expand Down Expand Up @@ -145,8 +145,8 @@ def helpForCommand(command, filename):
help += '; ' + option.help

optionSyntax += ' [{name}{arg}]'.format(
name= option.longName or option.shortName,
arg = '' if option.boolean else ('=' + option.argName)
name=(option.longName or option.shortName),
arg=('' if option.boolean else ('=' + option.argName))
)

help += '\n\nSyntax: ' + command.name() + optionSyntax + argSyntax
Expand All @@ -166,4 +166,3 @@ def usageForCommand(command):
usage += ' ' + arg.argName

return usage

10 changes: 5 additions & 5 deletions fblldbbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ def run(self, arguments, option):
pass


def evaluateExpressionValue(expression, printErrors = True):
def evaluateExpressionValue(expression, printErrors=True):
# lldb.frame is supposed to contain the right frame, but it doesnt :/ so do the dance
frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
value = frame.EvaluateExpression(expression)
if printErrors and value.GetError() is not None and str(value.GetError()) != 'success':
print value.GetError()
return value

def evaluateIntegerExpression(expression, printErrors = True):
def evaluateIntegerExpression(expression, printErrors=True):
output = evaluateExpression('(int)(' + expression + ')', printErrors).replace('\'', '')
if output.startswith('\\x'): # Booleans may display as \x01 (Hex)
output = output[2:]
elif output.startswith('\\'): # Or as \0 (Dec)
output = output[1:]
return int(output, 16)

def evaluateBooleanExpression(expression, printErrors = True):
def evaluateBooleanExpression(expression, printErrors=True):
return (int(evaluateIntegerExpression('(BOOL)(' + expression + ')', printErrors)) != 0)

def evaluateExpression(expression, printErrors = True):
def evaluateExpression(expression, printErrors=True):
return evaluateExpressionValue(expression, printErrors).GetValue()

def evaluateObjectExpression(expression, printErrors = True):
def evaluateObjectExpression(expression, printErrors=True):
return evaluateExpression('(id)(' + expression + ')', printErrors)
6 changes: 3 additions & 3 deletions fblldbinputhelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ def stop(self):
self.inputReader.SetIsDone(True)

def handleInput(self, inputReader, notification, bytes):
if (notification == lldb.eInputReaderGotToken):
if notification == lldb.eInputReaderGotToken:
self.callback(bytes)
elif (notification == lldb.eInputReaderInterrupt):
elif notification == lldb.eInputReaderInterrupt:
self.stop()

return len(bytes)
Loading