Sudzc Arc Version - Objc_Msgsend Call Causes Exc_Bad_Access Using 64-Bit Architecture

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



Leave a reply



Submit