📜 ⬆️ ⬇️

Debug Objective-C ARC retain

Sometimes situations arise when standard debugging tools are not enough.

For example, in iOS 4.1, it was possible to use valgrind in the simulator. And in Lion x86_64 and iOS 5, valgrind stopped working.
This is due to the 64-bit architecture and changes in the simulator (there are a number of valgrind
flaws).

With the transition to the ARC debugging retain method disappeared:
')
- (id) retain { // Break here to see who is retaining me. return [super retain]; } 



In my case, the clang compiler hack was the way out.

Configuration:
Platform: Lion x64_86
Xcode: 4.2.1 4D502
clang: 318.0.58 i686

1. Find out the compiler version

 $ clang --version Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn) ... 

2. Download and extract our clang version from Apple Open Source

http://opensource.apple.com/tarballs/
clang /

It may not be your version, in which case download as much as possible.
approximate, better which is newer.

 $ tar xzvf clang-318.0.45.tar.gz 

3. Patches clang

Replace the standard objc_retain call with objc_retain1.

 clang-318.0.45/src/tools/clang/lib/CodeGen/CGObjC.cpp:1554 > "objc_retain1"); 

4. We collect clang

 make RC_ProjectSourceVersion=1 RC_OS=macos RC_ARCHS=i686 TARGETS=i686 SRCROOT=`pwd` OBJROOT=`pwd`/build/obj DSTROOT=`pwd`/build/dst SYMROOT=`pwd`/build/sym 

The build will end with a rights-related error.

 chown: src/apple-gcc/1/clang-318.0.45/build/obj/stage1-install-x86_64/lib/c++: Operation not permitted make[4]: *** [do-installhdrs] Error 1 ... make[1]: *** [install] Error 1 

It's okay that install failed - the main binaries are and they are received.

 build/obj/stage1-install-x86_64/bin/clang 

Apple's scripts are unique, perhaps this can be solved by specifying the correct parameters,
maybe not (for example, to build gcc I had to patch build_gcc to disable
installation after assembly).

Attention! If you build gcc or llvm-gcc with the method specified in README.TXT, by default, make install will occur and your originals will be overwritten.
Therefore, before any actions you need to make a backup /
Developer / Platforms / iPhoneSimulator.platform / Developer / usr /.
Clang is not concerned because it has a different build configuration (tested on
versions of clang-318.0.45).

5. Install clang

Save the original and make symlink to a new one (only symlink, otherwise there will be an error due to
Differences in Developer / usr and stage1-install-x86_64 /).

 $ cd /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin $ mv clang clang.orig $ ln -s clang-318.0.45/build/obj/stage1-install-x86_64/bin/clang 

Is done. To complete the work you will need 2 versions of clang. Unmodified (without
patch p.3) - to collect most of the files that do not need debugging. AND
modified - for those files in which we will debug ARC retain. Choose
the build version in Xcode will have to be manually

 #   $ ln -s clang-318.0.45/build/obj/stage1-install-x86_64/bin/clang #  ,     clang.new $ ln -s clang-318.0.45/build/obj/stage1-install-x86_64/bin/clang.new clang 

Everything is clear with the compiler, now it's up to the project.

In any project file we add our objc_retain1 function, I got this
(prints backtrace):

 id objc_retain(id o); void *objc_retain1(void *o) { static void *b[10]; static int z = 10; static int n; static char **c; n = backtrace(b, z); c = backtrace_symbols(b, n); NSLog(@"objc_retain(%p):", o); for (int i = 0; i < n; i++) { NSLog(@"%s", c[i]); } return (__bridge void *)objc_retain((__bridge id)o); } 

In this function, you can put a breakpoint and catch small object hijackers.

Next, we build the project using an unmodified compiler so as not to catch
retain all objects (do not forget to clean up to remove the compiled files with the original compiler).
We replace the compiler with the modified one, save the necessary file, collect and
debugging in the simulator.

The CGObjC.cpp file contains other ARC functions that can also be intercepted.
(at the same time studying the inner world of ARC).
Link with ARC details:
http://clang.llvm.org/
docs / AutomaticReferenceCounting.html

* Paths may vary for different SDK versions.

Source: https://habr.com/ru/post/148099/


All Articles