SudzC ARC version - objc_msgSend call causes EXC_BAD_ACCESS using 64-bit architecture
OK - so after more hair-pulling and research, it finally dawned on me that it might be a 64-bit vs 32-bit issue. This was the first app I was working on since upgrading to the new Xcode. I went to Build Settings and changed the Architectures from "Standard architectures (including 64-bit) (armv7, armv7s, arm64)" to "Standard architectures (armv7, armv7s)". This fixed the issue!
I then went back and researched why this was happening. I found this Apple 64-bit transition guide: https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html
The document mentions the following:
Dispatch Objective-C Messages Using the Method Function’s Prototype An
exception to the casting rule described above is when you are calling
the objc_msgSend function or any other similar functions in the
Objective-C runtime that send messages. Although the prototype for the
message functions has a variadic form, the method function that is
called by the Objective-C runtime does not share the same prototype.
The Objective-C runtime directly dispatches to the function that
implements the method, so the calling conventions are mismatched, as
described previously. Therefore you must cast the objc_msgSend
function to a prototype that matches the method function being called.Listing 2-14 shows the proper form for dispatching a message to an
object using the low-level message functions. In this example, the
doSomething: method takes a single parameter and does not have a
variadic form. It casts the objc_msgSend function using the prototype
of the method function. Note that a method function always takes an id
variable and a selector as its first two parameters. After the
objc_msgSend function is cast to a function pointer, the call is
dispatched through that same function pointer.
Using this information, I changed the below line:
objc_msgSend(self.handler, self.action, self.value);
to:
id (*response)(id, SEL, id) = (id (*)(id, SEL, id)) objc_msgSend;
response(self.handler, self.action, output);
And all is working!
Hopefully this will help someone else...
obj_msgSend function pointer crash when build with 64bit arm64
Finally, I can reproduce the crash right now. Simply edit Build Scheme and change "Run YOURAPPNAME.app" from Debug to Release.
And right after I can reproduce this bug, I know how to fix it. Since my selector function type is void(does not return anything), I should not just copy what the question does (using "id").
By changing:
id (*response)(id, SEL, id) = (id (*)(id, SEL, id)) objc_msgSend;
response(self.target, self.successAction, category);
To:
void (*response)(id, SEL, id) = (void (*)(id, SEL, id)) objc_msgSend;
response(self.target, self.successAction, category);
It fixes!! Or a one-line code thanks to this commit on github:
((void(*)(id, SEL, id))objc_msgSend)(self.target, self.successAction, category);
EXC_BAD_ACCESS, code 1, iOS 7.0.x 64bit devices
I had similar problem. When you updated Xcode there was probably warning to "Validate Project setting". When you did that, there was checkbox to automatically select "Architectures". And this is where my problem lay.
To fix it change "Architectures" and "Valid Architectures" in build settings for Project AND Target to "armv7 armv7s" (right now you probably have selected Standard architectures) and set "Build Active Architectures only" to NO.
Sudzc with iOS 5 and ARC
In my case (SUDZC with ARC for IOS), I have replaced the folowing code in SoapRequest.m file;
CXMLNode* element = [[Soap getNode: [doc rootElement] withName:@"Body"] childAtIndex:0];
with
CXMLNode* element = [[Soap getNode: [doc rootElement] withName:@"soap:Body"] childAtIndex:0];
Somehow the respective function is searching for the root element with name "Body". After inspecting the soap envelope it is easy to see the root element's name is "soap:Body".
Sudzc ObjC code with ARC broken
Horrifically Easy solution.
Must be developing with my eyes closed.
It appears there is a glitch with Sudzc's ARC code gen that misses 2 import statements.
Just stuck:
#import "Soap.h"
#import "SoapObject.h"
Above the implementation in SoapObject.m
Sorted.
EXC_BAD_ACCESS in main.m after converting to ARC
BAD_EXC_ACCESS are a little tricky, mainly because they don't show up at the offending line which causes the error. Using lldb, you can use thread backtrace
to get an idea of what is causing it. This answer contains a great answer with a few ideas on how to troubleshoot similar problems.
sudzc generates bad soap request
I had the same problem and was able to fix it by removing the default namespace (xmlns=) altogether and search/replacing all method names, adding an explicit namespace as prefix
to all names.
Is it possible that NSZombie doesn't point out EXC_BAD_ACCESS with ARC?
Better than using the NSZombieEnabled, you should Profile the project, and use the Zombie instrument. When you do the same thing it should stop and say "zombie messaged", where you can click an arrow to see the class that is a zombie, and where it was allocated/deallocated.
I don't think the crash has to do with ARC, instead in viewDidUnload you are deallocating something, and then not setting a reference to nil - when you come back it tries to use the invalid reference.
Probably you would be better off if everything used ARC as it really helps to cure issues like this (the bug is very likely in the non-ARC code).
Related Topics
Add Segmented Control to Navigation Bar and Keep Title with Buttons
Implementing Unit Testing with iOS
Ios: Place Uiview on Top of Uitableview in Fixed Position
How to Check If a Framework Is Bitcode Supported for Xcode7
Allow Uiscrollview and Its Subviews to Both Respond to a Touch
How to Cast an Nsmutablearray to a Swift Array of a Specific Type
What's Always_Embed_Swift_Standard_Libraries with Cocoapods, Swift 3 and Xcode 8
iPhone Collecting Coremotion Data in the Background. (Longer Than 10 Mins)
iOS 11 Core Nfc - Any Sample Code
Autolayout Multiline Uilabel Cutting Off Some Text
Non Power of Two Textures in iOS
Swift 3: Expression Implicitly Coerced from 'Uiview' to Any
How to Show a Info Window in iOS Google Maps Without Tapping on Marker
How to Generate PDF File from a Xml/HTML Template in iOS
Facebooksdk and Bolts Conflicting Each Other (Duplicate Symbols) on Build