Thursday, October 27, 2011

Debugging static object destruction order

If you like to avoid the “static initialization order fiasco” by using construct on first use idiom but with a static object instead of a static object pointer, you might also run into static destruction order fiasco. One solution is to reorder the static constructors so that the destructors are called in the right order, by forcing the static object to be referenced before its first use.

In order to do decide how to reorder the destruction sequence, we need to tell how it will be carried out. The static destructors are called in reverse order the static constructors are called. Leveraging the fact that destructors are registered using __cxa_atexit (this is part of Itanium C++ ABI, which is adopted by Linux Standard Base and implemented in GCC) as soon as the constructor finishes, we can set breakpoint for __cxa_atexit to see the constructor order, which in turn means the destructors will be called in reverse.

The gdb recipe here will print the name of the function that contains the static object whenever the static object is constructed, but will continue execution.
(gdb) b __cxa_atexit  # assume this is breakpoint n
# set commands to automatically execute for breakpoint n
(gdb) commands n
>where 2
>continue
>end

(gdb) b __cxa_finalize
This allows you to generate a log of construction order without breaking and analyze it offline.

Friday, October 7, 2011

Xcode 4.1 for Lion and Apple App Store archive format

Today I had the (dis)pleasure of downloading Xcode 4.1 for Lion, which turns out to be packaged for App Store. I only have Leopard, so this is how I extracted the file content.

  • First I opened up xcode_4.1_for_lion.dmg, which is a regular hard disk image file.
  • After mounting, there is a InstallXcodeLion.pkg which turns out to be an xar file. To extract, run xar -x -f /Volumes/Install Xcode/InstallXcodeLion.pkg in an empty directory. I think this is the file that you would have downloaded over App Store.
  • After extraction, there are a few more files.
    • Distribution - an XML manifest for the App Store. Contains some JavaScript code that is used for the installer. Who'd have thought that Mac OS X installers use JavaScript for scripting?
    • InstallXcodeLion.pkg - contains yet another package for installation.
    • Resources - the license file and localization.
  • Inside InstallXcodeLion.pkg, there is a file Payload which is a cpio file. To extract, run cpio -i -F /path/to/InstallXcodeLion.pkg/Payload in another empty directory.
  • After extraction, you get an Applications folder with Install Xcode.app. This is supposedly what App Store saves to the Applications folder.
  • Attempting to run the mach-O binary in the command line results in: dyld: unknown required load command 0x80000022. It is LC_DYLD_INFO_ONLY.
  • All the sub-packages can be found in the Contents/Resources/Packages. They are xar packages, but with Bom, PackageInfo, Payload, and Scripts immediately inside. These .pkg files can actually be installed with the Installer that comes with Leopard. However, it is not clear if the binaries installed by these packages will suffer the LC_DYLD_INFO_ONLY issue.
This shows that with some script kiddie magic, you can install Xcode 4.1 on Leopard. Whether it will actually run or not is another thing.