Betcha can't debug that #2. Solution Part 1
If you look at the project, there seems to be offhand nothing problematic to it.
otool -L says (as expected):
FrameworkRosettaFuckup/build/Debug
Native/FrameworkRosettaFuckup.app/Contents/MacOS/FrameworkRosettaFuckup:
|
The code contained in main.framework, again, is just this:
@implementation NSString( URLFix) - (NSString *) standardizedURLPath { printf( "%s\n", __PRETTY_FUNCTION__); return( nil); } @end |
Checking the Xcode documentation reveals nothing for any standardizedURLPath method.
But a class-dump of Foundation shows, that this is a method defined on NSString! As class-dump /System/Library/Frameworks/Foundation.framework/Foundation | egrep -B 1 -A5 standardizedURLPath gives for the 10.6.4 Foundation Framework/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 751.29.0):
@interface NSString (NSURLPathUtilities) - (id)standardizedURLPath; - (id)stringByRemovingPercentEscapes; - (id)stringByAddingPercentEscapes; - (id)urlPathRelativeToPath:(id)arg1; @end |
And it has been defined on category, something which will be of great concern later on,
The way to debug this is using a combination of dyld and Objective-C runtime environment flags (see dyld(1) or export OBJC_HELP=YES for details). Technically OBJC_PRINT_REPLACED_METHODS suffices, but then there is less to talk about.
export DYLD_PRINT_LIBRARIES=YES export OBJC_PRINT_IMAGES=YES export OBJC_PRINT_CLASS_SETUP=YES export OBJC_PRINT_REPLACED_METHODS=YES
Here comes the output, thoughtfully filtered for easier reading with egrep 'NSString|standardizedURLPath|dyld:|IMAGES'. It's actually better to start the executable in the shell, because the debugger will start bash and arch beforehand, cluttering the output.
// // dyld loads our stuff // dyld: loaded: /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug Native/FrameworkRosettaFuckup.app/Contents/MacOS/FrameworkRosettaFuckup dyld: loaded: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation dyld: loaded: /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug Native/main.framework/Versions/A/main dyld: loaded: /usr/lib/libSystem.B.dylib dyld: loaded: /usr/lib/libobjc.A.dylib // // up to this point dyld just loaded what it was told to by the linker, now it needs to load dependent // frameworks and library to get things going // dyld: loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation dyld: loaded: /usr/lib/libauto.dylib dyld: loaded: /usr/lib/libicucore.A.dylib dyld: loaded: /usr/lib/libxml2.2.dylib // hmm couldn't that be loaded lazily ? I don't do xml dyld: loaded: /usr/lib/libz.1.dylib // i don't do compression either dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/CFNetwork // networking, not really dyld: loaded: /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration dyld: loaded: /System/Library/Frameworks/Security.framework/Versions/A/Security dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices dyld: loaded: /usr/lib/libstdc++.6.dylib dyld: loaded: /usr/lib/system/libmathCommon.A.dylib dyld: loaded: /usr/lib/libsqlite3.dylib // huh ??? dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices dyld: loaded: /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit dyld: loaded: /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration // O RLY ? dyld: loaded: /usr/lib/libbsm.0.dylib dyld: loaded: /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS dyld: loaded: /usr/lib/system/libkxld.dylib dyld: loaded: /usr/lib/libxslt.1.dylib // moar XML ... // // dyld loaded a whole lot of superfluous crap and some stuff I actually care about // dyld hands things over to the objective-c runtime, (how it does this, we will see later) // objc[364]: IMAGES: processing 30 newly-mapped images... objc[364]: IMAGES: loading image for /usr/lib/libobjc.A.dylib (preoptimized) (supports GC) objc[364]: IMAGES: loading image for /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (preoptimized) (supports GC) objc[364]: IMAGES: loading image for /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata (preoptimized) (supports GC) objc[364]: IMAGES: loading image for /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (preoptimized) (supports GC) objc[364]: IMAGES: loading image for /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug Native/main.framework/Versions/A/main objc[364]: IMAGES: loading image for /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug Native/FrameworkRosettaFuckup.app/Contents/MacOS/FrameworkRosettaFuckup // // it is interesting to note, that except for libobjc.A.dylib, // the frameworks containing ObjC code are "loaded" // in reverse order // of dependency. More on this later // objc[364]: CONNECT: attaching category 'NSString (NSUserDefaults_NSURLExtras)' objc[364]: CONNECT: attaching category 'NSString (NSUnpublishedEOF)' objc[364]: CONNECT: attaching category 'NSString (NSURLPathUtilities)' objc[364]: CONNECT: attaching category 'NSString (NSURLUtilities)' objc[364]: CONNECT: attaching category 'NSString (NSScriptingComparisonMethods)' objc[364]: CONNECT: attaching category 'NSString (NSURLExtras)' objc[364]: CONNECT: attaching category 'NSString (NSURLExtrasInternal)' objc[364]: CONNECT: attaching category 'NSString (NSStringOtherEncodings)' objc[364]: CONNECT: attaching category 'NSString (NSExtendedStringPropertyListParsing)' objc[364]: CONNECT: attaching category 'NSString (NSComparisonMethods)' objc[364]: CONNECT: attaching category 'NSString (NSScriptSuiteDebugging)' objc[364]: CONNECT: attaching category 'NSString (NSScriptAppleEventConversion)' objc[364]: REPLACED: -[NSObject isNSString__] by category NSKindOfAdditions (IMP was 0x90718df0 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation), now 0x94579bee (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation)) objc[364]: CONNECT: attaching category 'NSString (NSKindOfAdditions)' objc[364]: CONNECT: attaching category 'NSString (NSStringPortCoding)' objc[364]: CONNECT: attaching category 'NSString (NSPathUtilities)' objc[364]: CONNECT: attaching category 'NSString (NSSearchMethods)' objc[364]: CONNECT: attaching category 'NSString (_NSMetadataQueryExtensions)' objc[364]: CONNECT: attaching category 'NSString (NSDistantString)' objc[364]: CONNECT: attaching category 'NSString (NSDecimalExtension)' objc[364]: CONNECT: attaching category 'NSString (NSCFAdditions)' objc[364]: CONNECT: attaching category 'NSString (URLFix)' objc[364]: REPLACED: -[NSString standardizedURLPath] by category URLFix (IMP was 0x946eb3f1 (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation), now 0x5f18 (/Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug Native/main.framework/Versions/A/main)) // and that's what we are looking for. // -[NSString standardizedURLPath] is overwriting the method defined in Foundation.framework. // So stuff should work as expected objc[364]: CONNECT: class 'NSString' now connected objc[364]: CONNECT: class 'NSStringPredicateOperator' now connected -[NSString(URLFix) standardizedURLPath] // and it does, as there is no magic in computing // just lack of information sometimes. |
Lets see how Rosetta does it. otool sees no difference in the frameworks linked:
FrameworkRosettaFuckup/build/Debug
PPC/FrameworkRosettaFuckup.app/Contents/MacOS/FrameworkRosettaFuckup:
|
And a run in the shell with aforementioned environment variables set, gives this output:
dyld: loaded:
/Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug
PPC/FrameworkRosettaFuckup.app/Contents/MacOS/FrameworkRosettaFuckup dyld: loaded: /usr/libexec/oah/Shims/Interposers.dylib // this is Rosetta interposing and translating the PPC code for us. Does it trip up something ?? dyld: loaded: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation dyld: loaded: /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug PPC/FrameworkRosettaFuckup.app/Contents/MacOS/../Frameworks/main.framework/Versions/A/main dyld: loaded: /usr/lib/libSystem.B.dylib dyld: loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation dyld: loaded: /usr/lib/libauto.dylib dyld: loaded: /usr/lib/libicucore.A.dylib dyld: loaded: /usr/lib/libobjc.A.dylib dyld: loaded: /usr/lib/libxml2.2.dylib dyld: loaded: /usr/lib/libz.1.dylib dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/CFNetwork dyld: loaded: /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration dyld: loaded: /System/Library/Frameworks/Security.framework/Versions/A/Security dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices dyld: loaded: /usr/lib/libstdc++.6.dylib dyld: loaded: /usr/lib/system/libmathCommon.A.dylib dyld: loaded: /usr/lib/libsqlite3.dylib dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices dyld: loaded: /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices dyld: loaded: /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit dyld: loaded: /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration dyld: loaded: /usr/lib/libbsm.0.dylib dyld: loaded: /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS dyld: loaded: /usr/lib/system/libkxld.dylib dyld: loaded: /usr/lib/libxslt.1.dylib // // nothing else different there // objc[439]: OBJC_PRINT_IMAGES: log image and library names as they are loaded objc[439]: OBJC_PRINT_VTABLE_IMAGES: print vtable images showing overridden methods objc[439]: IMAGES: processing 31 newly-mapped images... objc[439]: IMAGES: loading image for /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata (supports GC) objc[439]: IMAGES: loading image for /usr/lib/libobjc.A.dylib (supports GC) objc[439]: IMAGES: loading image for /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (supports GC) objc[439]: IMAGES: loading image for /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug PPC/FrameworkRosettaFuckup.app/Contents/MacOS/../Frameworks/main.framework/Versions/A/main objc[439]: IMAGES: loading image for /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (supports GC) objc[439]: IMAGES: loading image for /Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug PPC/FrameworkRosettaFuckup.app/Contents/MacOS/FrameworkRosettaFuckup // the order of images though is very much different than it was before // which is significant objc[439]: CONNECT: attaching category 'NSString (URLFix)' // Our category gets loaded objc[439]: CONNECT: attaching category 'NSString (NSUserDefaults_NSURLExtras)' objc[439]: CONNECT: attaching category 'NSString (NSUnpublishedEOF)' objc[439]: CONNECT: attaching category 'NSString (NSURLPathUtilities)' objc[439]: REPLACED: -[NSString standardizedURLPath] by category NSURLPathUtilities (IMP was 0xb7f44 (/Volumes/Users/nat/Downloads/FrameworkRosettaFuckup/build/Debug PPC/FrameworkRosettaFuckup.app/Contents/MacOS/../Frameworks/main.framework/Versions/A/main), now 0x95582d2c (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation)) // // Now Foundation overwrote our implementation ! // objc[439]: CONNECT: attaching category 'NSString (NSURLUtilities)' objc[439]: CONNECT: attaching category 'NSString (NSScriptingComparisonMethods)' objc[439]: CONNECT: attaching category 'NSString (NSURLExtras)' objc[439]: CONNECT: attaching category 'NSString (NSURLExtrasInternal)' objc[439]: CONNECT: attaching category 'NSString (NSStringOtherEncodings)' objc[439]: CONNECT: attaching category 'NSString (NSExtendedStringPropertyListParsing)' objc[439]: CONNECT: attaching category 'NSString (NSComparisonMethods)' objc[439]: CONNECT: attaching category 'NSString (NSScriptSuiteDebugging)' objc[439]: CONNECT: attaching category 'NSString (NSScriptAppleEventConversion)' objc[439]: REPLACED: -[NSObject isNSString__] by category NSKindOfAdditions (IMP was 0x96cce1f8 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation), now 0x9552801c (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation)) objc[439]: CONNECT: attaching category 'NSString (NSKindOfAdditions)' objc[439]: CONNECT: attaching category 'NSString (NSStringPortCoding)' objc[439]: CONNECT: attaching category 'NSString (NSPathUtilities)' objc[439]: CONNECT: attaching category 'NSString (NSSearchMethods)' objc[439]: CONNECT: attaching category 'NSString (_NSMetadataQueryExtensions)' objc[439]: CONNECT: attaching category 'NSString (NSDistantString)' objc[439]: CONNECT: attaching category 'NSString (NSDecimalExtension)' objc[439]: CONNECT: attaching category 'NSString (NSCFAdditions)' objc[439]: CONNECT: class 'NSString' now connected objc[439]: CONNECT: class 'NSStringPredicateOperator' now connected |
So this was the solution, that could have gotten you that luxury sedan, if you could have debugged that. Next up, lets dig a little deeper into the objc and dyld source.
Post a comment
All comments are held for moderation; basic HTML formatting accepted.