Why are device and simulator builds different? - iphone

I'm referencing two static libraries. I build them in debug-simulator mode and all works well with my app. I then create debug-iphone builds and push my app to the device. It breaks with this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFString sizeWithCGFont:pointSize:constrainedToSize:]: unrecognized selector sent to instance 0x24320'
Then the SIGABRT error shows.
Why would this work fine on the simulator and only manifest on the device?
-- EDIT --
Finally figured out a work around, at least for running on the device but now not the simulator. The method that is throwing the exception is a class I'm using for fonts. It is part of staticLibA, for example, which is the library that was having issues. I included staticLibA as a reference in the target app and also the .m file of the problem class. I already had a reference to its header file, which is a category in NSString. Is that why it didn't work until I included the .m file?
If I try to run it in the simulator, I get a duplicate object error in the build output folder for the above class.

I couldn't tell you why your issue is only presenting itself on the device at the moment - perhaps you need to clean both builds and try recompiling them?
In any case, the exception message shown is completely valid. There is no (public) method named -[NSString sizeWithCGFont:pointSize:constrainedToSize:]. Are you trying to call one of the sizeWithFont: methods on NSString anywhere?
Edit: Looks like the sizeWithCGFont:pointSize:constrainedToSize: is from cocos-2d, which I'm guessing would be one of your static libraries. The major significant different between simulator and device builds is the build architecture - the simulator's architecture is the architecture of your own machine (i386), while device builds are for armv6 or armv7. Are you sure your static libraries are built for the right architectures?

Simulator builds are compiled for the Intel platform since your computer is on the x86 (or x86_64) architecture.
The device builds compile to the arm6 (or arm7) architecture.
You can't use a library that's been compiled for one on the other. The assembly code from each isn't compatible.

I have had this problem show up when I was releasing an object incorrectly. So I would have a pointer to a unallocated object. So when I called a function on the object, it would say that I was calling the function on a NSCFString object. Probably because the memory was reused for a NSString object. I fixed it by finding my extra release and removing it.

Related

NSInvalidArgumentException', reason: '[__NSCFString JSONObject]' with PhoneGap Camera

I have been working with PhoneGap to access the camera, which works locally when built to the iPhone, but when I upload to TestFlight, the same method fails and gives me the following:
'NSInvalidArgumentException', reason: '[__NSCFString JSONObject]'
The arguments that are being passed are as follows:
[["Camera1856949628","Camera","takePicture",[25,0,1,100,100,1,0,false,false,false,null,0]]]
From what I gather its failing in CDVJSON.m when converting an NSString to JSONObject which in turn is an NSArray.
Any suggestions on what might be causing this?
Because your code don't use the JSONObject until runtime. So CDVJSON.m didn't linked in the app.
Fixed the issue by adding "Other Linker Flags: -all_load" in your project. As suggested by this answer: https://stackoverflow.com/a/17581430/2570865

Difficulties getting iOS 5 app running on iOS 4

I have an iPhone app that with deployment target 4.0 and base sdk 5.0. The app runs fine on an iOS 5 simulator but when I stat the 4.3 simulator the app chrashes and I get this:
dyld: lazy symbol binding failed: Symbol not found:
_objc_retainAutoreleasedReturnValue Referenced from: /Users/joakim/Library/Application Support/iPhone
Simulator/4.3.2/Applications/F6CE76EA-DA7E-4BAC-A3AC-3CE2B51C0CD9/PingPalARC.app/PingPalARC
Expected in:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
dyld: Symbol not found: _objc_retainAutoreleasedReturnValue
Referenced from: /Users/joakim/Library/Application Support/iPhone
Simulator/4.3.2/Applications/F6CE76EA-DA7E-4BAC-A3AC-3CE2B51C0CD9/PingPalARC.app/PingPalARC
Expected in:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
sharedlibrary apply-load-rules all (gdb)
The project does not use ARC by default, however there are a few classes for with i have turned on ARC with the -fobjc-arc flag under compile sources
I do not use any weak references and I do not use storyboards, so I can not see why my app should not work on iOS 4.x. Can anyone tell me what I have missed in order for my app to work on both iOS 4 and 5.
Added Frameworks:
System Configuration
Map Kit
CFNetwok
Core Location
You are using ARC, which is not built in to iOS 4. Did you set your deployment target to 4, so the arclite library is included for you? https://devforums.apple.com/message/588316
(Ah, it sounds like you did, but aren't telling the IDE that you are using ARC. So you will have to include it yourself.)
Not really an answer, but some more information in case it helps someone more knowledgable than me...
objc_retainAutoreleasedReturnValue(obj) is new to iOS 5 and does pretty much what the name says. Conceptually, if the nominated object is in the autorelease pool then it's taken out of there, implicitly retaining it, and a suitable release is added at a later point. So it's a way of avoiding the memory bottleneck problem that can occur when conceptually temporary objects pile up in the autorelease pool. So it's an optimisation, not a new piece of behaviour.
The ARC compiler will have inserted that in one of your ARC files where some method receives an autoreleased object. As you say, it's unrelated to both weak references and storyboards and is logically something you could simply not do in order to retain iOS 4 compatibility.
Having said all that, I'm not completely confident of a workaround other than the obvious but probably very hard to stomach — modify your ARC classes so that they never receive autoreleased objects or switch off ARC entirely. Apple don't allow dynamically linked libraries to be deployed so I can't think of a safe way to offer an objc_retainAutoreleasedReturnValue alternative for iOS 4 devices.
Add all the temporary variable declarations inside autoreleasepool block inside the function.

App crashes on Apple LLVM 3.0 but works OK on LLVM GCC 4.2

I have a very strange crash when using the Apple LLVM 3.0 compiler.
So there is some code, that uses Assimp to load assets and create the scene (I've excluded all my code and even then it crashes):
aiScene* ai_scene = const_cast<aiScene*>(aiImportFileFromMemory(fileBuf, fInfo.uncompressed_size, aiProcessPreset_TargetRealtime_MaxQuality, NULL));
delete ai_scene;
Here is the screenshot of the stack trace for GCC:
And here is for LLVM:
In LLVM version destructor is called twice (and probably that's why I've got a crash).
I should also mention that all destructor code is located in header file and crashes only on device (tested on iPod 4 and iPad 2).
Is it a bug in LLVM compiler (probably in generation of arm assembly) or did I miss something?
Edit:
in case someone has similar problem use aiReleaseImport(scene) instead of delete scene;
You are not supposed to delete that pointer at all. Read the documentation. It clearly states that you should not attempt to free it in any way.
If the call succeeds, the contents of the file are returned as a
pointer to an aiScene object. The returned data is intended to be
read-only, the importer keeps ownership of the data and will destroy
it upon destruction. If the import fails, NULL is returned. A
human-readable error description can be retrieved by calling
aiGetErrorString().
And in addition, the documentation explicitly states that it's read-only, so do not const_cast the const away.
I had a similar problem earlier, and it was quite rare because I go no responses (other than my own) to that problem AppStore build crashes on launch on iPhone 3g and iPod Touch
It'd crash only on iPhone 3g, and on an old iPod touch.

Application with static library runs on simulator but not on actual device

I have an monotouch application that includes an objective-c static library. The application runs correctly on the simulator, but when I try run the app on my iPhone 3GS, it crashes on startup. These are the steps that I have taken to try get it working:
Compiled the static library in Xcode with Device specified and active architecture set at armv6 and at armv7 (I am not sure which is correct, but I tried both and neither worked).
Under the project info I set code signing identity to my developer key.
In MonoDevelop I have included the static library in the application project options by setting the additional monotouch arguments under iPhone build to have the following value (this is identical to what is set for iPhoneSimulator):
-v -v -v -gcc_flags "-lstdc++ -I${ProjectDir}/Ultralite/Include -L${ProjectDir}/Ultralite -lUltralite -force_load ${ProjectDir}/Ultralite/libUltralite.a"
When I try run the application, it crashes on startup (so the application screen does not even appear). In MonoDevelop all that I see is the following exception message:
Exception of type 'Mono.Debugger.Soft.VMDisconnectedException' was thrown.
All that I see in the device log in Xcode is the following:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_PROTECTION_FAILURE at 0x2fd00f24
If I remove the -gcc_flags option from the project options, then the application starts up, but crashes at the first attempt at accessing the static library. So it is definitely something to do with the static library that is causing the application to crash on startup.
I have no idea where to even begin with solving this, and so really need some help on this one. Anyone got any ideas as to what is wrong with the static library that I am including, or know where I can get more information about what is going wrong? The KERN_PROTECTION_FAILURE message in the crash report is really not giving me much to work with.
Update:
I have created a simple Hello World application which has one button, which when clicked calls a method sayHello in a static library. Even with this basic example I encountered the same problem; namely that it runs on the simulator but not on the actual device. I have uploaded my helloworld example to github. I would really appreciate it if someone could help me in getting this working. Here is the Hello World sample:
https://github.com/BruceHill/HelloWorld
This includes a folder for the basic application, a folder with the objective-c static library and then finally a folder for the btouch definition. I call btouch with the parameter -outdir=. to build Messaging.g.cs and UltraliteManager.g.cs which I then include in the MonoTouch application.
I had to make two changes to get this working correctly on the iphone:
linker behavior in the build options had to have the option Link all assemblies set.
I had to add -framework Security to the gcc_flags.
So additional monotouch arguments under the build options had to have the following value:
-v -v -v -gcc_flags "-framework Security -lstdc++ -I${ProjectDir}/Ultralite/Include -L${ProjectDir}/Ultralite -lUltralite -force_load ${ProjectDir}/Ultralite/libUltralite.a"
The reason I had to add the Security framework is that it seems MonoTouch includes this framework when Don't link is specified in the build options, but does not include it when the other two options are set. I determined this by comparing the build logs for the different options.
Open XCode Organizer. Plug in your device. Then look at the crashes. The data will symbolicate and you'd at least see at what point it failed.
I had a similar problem with MonoTouch linking a 3rd party library through BTouch. Same exception types and codes.
You have to get the source code for that 3rd party library and compile it with THUMB disabled. XCode has this option, just do a search for THUMB in the options. libUltralite.a will end up being a little bit larger in size.
Try adding "-ObjC" to your linker flags.
Update:
There seems to be a some issues regarding static libraties. You may also try to use the -all_load flag: What does the -all_load linker flag do?

iPhone: Using static library in an application crashes the device but not the iphone simulator

I have a library I made, and now I want to utilize it in an application. I've believe I've properly linked to the library. Here are all the things I've done:
Set the header search path
Set other linker flags to "-ObjC"
Added the static library xcode project
Made sure the lib.a was listed as a framework target
Added the library as a direct dependency
Like I said in the title, I've successfully run the app with the static library in the simulator. Once I try testing the app using the device, it crashes the second it has to use a function from the library:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSDate firstOfCurrentMonth]: unrecognized selector sent to class 0x3841bb44'
2009-10-10 12:45:31.159 Basement[2372:207] Stack:
This is due to a bug in the current SDK linker. See this post for more information on the problem and possible workarounds. (also see this post.)
Update:
Another thing you can try is to remove the static library and include the library's source files directly in the application's project. I was facing a similar static library linking issue and that's what I ended up falling back on to get it to run successfully. If that works (however gross a workaround it may be) then it's definitely a linker issue.
I ran into this problem recently. I was unable to get the -all_load to work, when I noticed that another category I had DID work. I was lazy for this category and included it in with another file.
I eventually created a dummy class (no methods, instance variables) and included the implementation of my categories in the .m file for that dummy class. After doing this my categories started working even after I removed the -all_load flag.
This was on iPhone OS 3.1.3.
This certainly is not the RIGHT way to fix it, but it seemed to work.
Full sample code is on my blog for my (trivial) categories.