def run(self, arguments, options): expression = arguments[0] match = re.match(r'([-+])*\[(.*) (.*)\]', expression) if not match: print 'Failed to parse expression. Do you even Objective-C?!' return expressionForSelf = objc.functionPreambleExpressionForSelf() if not expressionForSelf: print 'Your architecture, {}, is truly fantastic. However, I don\'t currently support it.'.format(arch) return methodTypeCharacter = match.group(1) classNameOrExpression = match.group(2) selector = match.group(3) methodIsClassMethod = (methodTypeCharacter == '+') if not methodIsClassMethod: # The default is instance method, and methodTypeCharacter may not actually be '-'. methodTypeCharacter = '-' targetIsClass = False targetObject = fb.evaluateObjectExpression('({})'.format(classNameOrExpression), False) if not targetObject: # If the expression didn't yield anything then it's likely a class. Assume it is. # We will check again that the class does actually exist anyway. targetIsClass = True targetObject = fb.evaluateObjectExpression('[{} class]'.format(classNameOrExpression), False) targetClass = fb.evaluateObjectExpression('[{} class]'.format(targetObject), False) if not targetClass or int(targetClass, 0) == 0: print 'Couldn\'t find a class from the expression "{}". Did you typo?'.format(classNameOrExpression) return if methodIsClassMethod: targetClass = objc.object_getClass(targetClass) found = False nextClass = targetClass while not found and int(nextClass, 0) > 0: if classItselfImplementsSelector(nextClass, selector): found = True else: nextClass = objc.class_getSuperclass(nextClass) if not found: print 'There doesn\'t seem to be an implementation of {} in the class hierarchy. Made a boo boo with the selector name?'.format(selector) return breakpointClassName = objc.class_getName(nextClass) breakpointFullName = '{}[{} {}]'.format(methodTypeCharacter, breakpointClassName, selector) breakpointCondition = None if targetIsClass: breakpointCondition = '(void*)object_getClass({}) == {}'.format(expressionForSelf, targetClass) else: breakpointCondition = '(void*){} == {}'.format(expressionForSelf, targetObject) print 'Setting a breakpoint at {} with condition {}'.format(breakpointFullName, breakpointCondition) lldb.debugger.HandleCommand('breakpoint set --fullname "{}" --condition "{}"'.format(breakpointFullName, breakpointCondition))
def run(self, arguments, options): expression = arguments[0] methodPattern = re.compile(r""" (?P<scope>[-+])? \[ (?P<target>.*?) (?P<category>\(.+\))? \s+ (?P<selector>.*) \] """, re.VERBOSE) match = methodPattern.match(expression) if not match: print 'Failed to parse expression. Do you even Objective-C?!' return expressionForSelf = objc.functionPreambleExpressionForSelf() if not expressionForSelf: print 'Your architecture, {}, is truly fantastic. However, I don\'t currently support it.'.format(arch) return methodTypeCharacter = match.group('scope') classNameOrExpression = match.group('target') category = match.group('category') selector = match.group('selector') methodIsClassMethod = (methodTypeCharacter == '+') if not methodIsClassMethod: # The default is instance method, and methodTypeCharacter may not actually be '-'. methodTypeCharacter = '-' targetIsClass = False targetObject = fb.evaluateObjectExpression('({})'.format(classNameOrExpression), False) if not targetObject: # If the expression didn't yield anything then it's likely a class. Assume it is. # We will check again that the class does actually exist anyway. targetIsClass = True targetObject = fb.evaluateObjectExpression('[{} class]'.format(classNameOrExpression), False) targetClass = fb.evaluateObjectExpression('[{} class]'.format(targetObject), False) if not targetClass or int(targetClass, 0) == 0: print 'Couldn\'t find a class from the expression "{}". Did you typo?'.format(classNameOrExpression) return if methodIsClassMethod: targetClass = objc.object_getClass(targetClass) found = False nextClass = targetClass while not found and int(nextClass, 0) > 0: if classItselfImplementsSelector(nextClass, selector): found = True else: nextClass = objc.class_getSuperclass(nextClass) if not found: print 'There doesn\'t seem to be an implementation of {} in the class hierarchy. Made a boo boo with the selector name?'.format(selector) return breakpointClassName = objc.class_getName(nextClass) formattedCategory = category if category else '' breakpointFullName = '{}[{}{} {}]'.format(methodTypeCharacter, breakpointClassName, formattedCategory, selector) if targetIsClass: breakpointCondition = '(void*)object_getClass({}) == {}'.format(expressionForSelf, targetClass) else: breakpointCondition = '(void*){} == {}'.format(expressionForSelf, targetObject) print 'Setting a breakpoint at {} with condition {}'.format(breakpointFullName, breakpointCondition) if category: lldb.debugger.HandleCommand('breakpoint set --skip-prologue false --fullname "{}" --condition "{}"'.format(breakpointFullName, breakpointCondition)) else: breakpointPattern = '{}\[{}(\(.+\))? {}\]'.format(methodTypeCharacter, breakpointClassName, selector) lldb.debugger.HandleCommand('breakpoint set --skip-prologue false --func-regex "{}" --condition "{}"'.format(breakpointPattern, breakpointCondition))