« October 2010 | Main | December 2010 »

November 2010 Archives

November 1, 2010

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:
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 751.29.0)
@executable_path/../Frameworks/main.framework/Versions/A/main (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.29.0)

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:
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 751.29.0)
@executable_path/../Frameworks/main.framework/Versions/A/main (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.29.0)

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.

November 4, 2010

Foundation Curiosity: NSSet as a property list

Why is it, that you can print NSSet as a property list, but you can't parse it ?

main.m
//  Coded by Nat! on 4.11.10, Mulle KybernetiK
#import <Foundation/Foundation.h>


int   main( int argc, char **argv) 
{
   NSAutoreleasePool      *pool;
   NSString               *s;
   NSSet                  *set;
   NSData                 *data;
   NSPropertyListFormat   format;
   id                     plist;   

   pool  = [NSAutoreleasePool new];
   
   set   = [NSSet setWithObjects:@"VfL", @"Bochum", @"1848", nil];
   s     = [set description];
   data  = [s dataUsingEncoding:NSUTF8StringEncoding];
   plist = [NSPropertyListSerialization 
                   propertyListFromData:data
                       mutabilityOption:NSPropertyListImmutable
                                 format:&format 
                       errorDescription:NULL];

   NSLog( @"plist %@ could %sbe parsed.", set, [plist isEqual:set] ? "" : "NOT ");

   [pool release];
   return( 0);
}

[Switching to process 48017]
Running…
2010-11-04 21:21:25.906 SetAsPlist[48017:a0f] plist {(
    VfL,
    Bochum,
    1848
)} could NOT be parsed.

November 21, 2010

PDF Creation, Image Shrinking, Hyperlinks

Just some stuff I learned, producing a very very simple flyer in a few hours instead of the few minutes it should have taken:
  • Using Omnigraffle 5.2.3 it's apparently not possible to print "http:" actions into the PDF.
  • You can use the Colorsync Utility to compress the images in the PDF. But you need to copy an existing filter to change the parameters (drove me nuts at first)
  • Colorsync Utility will also strip out the hyperlinks during the save of a PDF. So this is probably a feature of Mac OS X ?
  • Or is it ? Because you can use Preview to post-process a http://www.omnigroup.com/applications/omnigraffle/ and annotate hyperlinks. These then save OK.
  • But you can't overlay an email-address with a hyperlink area, as the generic text to mail-link parser of Preview takes precedence.

November 25, 2010

Wie ruiniert man den Planeten noch schneller ?

Ausnahmsweise mal was Politisches, aber hier geht etwas so schreiend, bekloppt schief und es scheint kaum jemanden aufzufallen. Es geht um Biosprit. Ich dachte das Thema wäre durch, aber die EU hat wohl mal wieder zugeschlagen und jetzt kommt E10.

Liest man die E10 Broschüre, dann steht da:

Was spricht für die Verwendung von E 10?

Die Beimischung von Ethanol zum Benzin hat 2 entscheidende Vorteile:
  • Bioethanol wird aus Pflanzen, also regenerativen Quellen, gewonnen und reduziert damit den Ausstoß â€¨des Klimagases CO2.
  • Durch die Verwendung von nachwachsenden Biokraftstoffen werden die Erdölreserven geschont.

Aber was spricht denn vielleicht dagegen ? Das darf man sich selber überlegen...

Was spricht gegen die Verwendung von E 10?

Die Beimischung von Ethanol zum Benzin hat 1 entscheidenden Nachteil:
  • Aus Pflanzen kann man Biosprit machen oder sie essen. Aus einer Möhre werden selbst duch Parteitagsbeschlüsse, ganz, ganz starkes Hoffen oder Beten nicht zwei.

  • Da es weltweit eher zuwenig als zuviele Nahrungsmittel gibt, braucht man auf der Erde also insgesamt mehr Produkte der Agrarindustrie. Daraus ergeben sich folgende Konsequenzen:
    1. Bestehendes Ackerland wird für Biosprit verwendet, was die Nahrungsmittel verknappt. Ergo steigen die Nahrungsmittelpreise. Das führt absehbar in den armen Ländern zu Hunger, Unruhen und Instabilität. (-> glaub ich nich)
    2. Die letzten Naturreste werden gerodet. So schon länger in Asien zu beobachten: Urwald weg, Ölpalmen hin. (-> glaub ich nich)
    3. Ackerland wird teurer und irgendwann für Kleinbauern wohl unerschwinglich. (-> glaub ich nich)
    4. Der Druck nach mehr Ausbeute auf den bestehenden Ackerflächen, kann, natürlich..., "nur mit Hilfe der Gentechnik" gelöst werden. Also dürften hier in absehbarer Zeit alle Schranken fallen. (-> glaub ich nich)

Was kann man dagegen machen ?

Als Konsument kann man einen der Ultimate Kraftstoffe tanken, da diese noch rein fossil sind (das mach ich). Nächste mal vielleicht nicht Idioten wählen.


Und wer hat's verbockt ?

Massgeblich Herr Sigmar Gabriel (Motto der SPD: "Wir sind die Kraft, die stets das Gute will und stets das Böse schafft.").

About November 2010

This page contains all entries posted to Nat!'s Web Journal in November 2010. They are listed from oldest to newest.

October 2010 is the previous archive.

December 2010 is the next archive.

Many more can be found on the main index page or by looking through the archives.