2. Short introduc,on
Peter Adam Wiesner
So0ware Engineer @ Skyscanner
iOS run(me, code architectures
cyberpunk
Twi$er - @peteee24
E-mail - peter.wiesner@skyscanner.net
Github - @wiesnerpe<
3. What is the dream of every developer?
Development of apps, that the users love and find them useful :)
What is the coders worst nightmare?
4. Human nature
One key characteris.c of the human evolu.on is , that we try to
create tools for the problems we already solved. This helps us
crea.ng more complex systems
Same for apps. More and more classes are working together to
achieve a goal
.. and we trust every class will do its job correctly
5. Try to handle the situa0on
Unit tests << Integra-on tests << System tests << ?
tes%ng level == number of dependency, that need to be
covered
we should simulate real environments
can't write unit test for every inout-output configura5on, hope we
covered the edge cases
6. Best defence is a,ack
Not new idea(Ne,lix)
How to apply this to mobile apps?
Change some dependencies' behaviour, try to keep the system in
unstable state
7. Theory
Need a tool that can replace arbitary method of arbitary class to
behave in an arbitary different way
8. Dixie history
1. Unit tests were strangely succeeding ➡ Chaos Monkey
2. Collec9ng ideas ➡ make a library
3. Research lab ➡ Beta
4. Open source
10. How does ObjC work?
1. [self doStuff:@2];
2. (id(*)(id, SEL,
id))objc_msgSend(self,@selector(doStuff:), @2);
3. Looking up in the methods of the class and superclass
4. if found ➡ jump to the registered IMP func>on-pointer
11. Swizzling
"replacing regitered IMP func3on-pointers with the help of
Objec3ve-C run3me C func3ons"
— NSHipster
• class_addMethod
• class_replaceMethod
• imp_implementationWithBlock
• We need to know the signature of the target method, when
wri5ng the code
12. Prepare for the unknown
• Need a general block, that can be used to swizzle arbitrary
method
• Long list of return and param types: BOOL, short, double, id,
selector, block...
• Idea:
• use variadic parameters
• parse them so they will be objects
• copy the code for every type by defining macros
13. Something like this
imp_implementationWithBlock([type]^(id victim, ...){
//Create call environment
//Parse parameters
//Call chaos provider block
block(victim, environment)
//Decide what to return
return ([type]*)environment.returnValue
})
14. Using the unknown
Some%mes we need to call an unknown func%on (previous problem
from the side of the caller)
if (numOfParams == 1)
f(obj1);
else if (numOfParams == 2)
f(obj1, obj2)
else ...
➡ Not scalable :(
15. Using the unknown
Macro magic
#define o(object) /
type(object) == @encode(int) ? (int)object : /
type(object) == @encode(double) ? (double)object : /
...
➡ ?: does not support different return types (C++ macros are
working in compile 8me)
16. Using the unknown
FFI(Foreign Func-on interface)
ffi_cif cif; //call object
ffi_type *args[1]; //arg types
void *values[1]; //arg values
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args)
ffi_call(&cif, IMP, &returnValue, values);
➡ 10% unknown crashes for class methods + dependency
17. Using the unknown
NSInvoca)on - FFI by Apple
invokeUsingIMP - private method, that does not use
objc_msgSend
NSMethodSignature* signature = ...;
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
//set args
[invocation invokeUsingIMP:implementation];
//get return value
18. Toolbox of opportuni.es
This is only the first step, how to advance?
➡ Combine behaviours -> Nil, Block, Composit, ExcepAon
➡ Invent new tools -> AST parsing, dependency recogniAon
19. To takeaway
1. Hope for the best, expect the worst, beside wri4ng unit tests,
challenge the applica4on with different inputs, in real life
environment
2. To simulate strange scenarios, Dixie is a good tool:
h@ps://github.com/Skyscanner/Dixie