Exc_Bad_Access Automatic Handling

EXC_BAD_ACCESS automatic handling

EXC_BAD_ACCESS doesn't generate an exception so you first function doesn't work with the case. It generates a signal SIGSEGV or SIGBUS.

Please refer to Handling unhandled exceptions and signals by Cocoa with Love.

Update

I just checked the source code of LLDB. It might be TARGET_EXC_BAD_ACCESS = 0x91.

In RNBRemote.h:

/* We translate the /usr/include/mach/exception_types.h exception types
(e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard
coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
values in its include/gdb/signals.h. */

#define TARGET_EXC_BAD_ACCESS 0x91
#define TARGET_EXC_BAD_INSTRUCTION 0x92
#define TARGET_EXC_ARITHMETIC 0x93
#define TARGET_EXC_EMULATION 0x94
#define TARGET_EXC_SOFTWARE 0x95
#define TARGET_EXC_BREAKPOINT 0x96

and in RNBRemote.cpp:

// Translate any mach exceptions to gdb versions, unless they are
// common exceptions like a breakpoint or a soft signal.
switch (tid_stop_info.details.exception.type)
{
default: signum = 0; break;
case EXC_BREAKPOINT: signum = SIGTRAP; break;
case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break;
case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break;
case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break;
case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break;
case EXC_SOFTWARE:
if (tid_stop_info.details.exception.data_count == 2 &&
tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
signum = tid_stop_info.details.exception.data[1];
else
signum = TARGET_EXC_SOFTWARE;
break;
}

How to set a new handler/responder for EXC_BAD_ACCESS crashes

As Carl mentions, intercepting crashing events on iOS (and macOS) is fraught with peril for variety of reasons. I was the Crashlytics SDK maintainer for a while, and I would recommend strongly against doing it.

But, it definitely is possible.

One thing that seems to trip people up a lot is the relationship between signals, exceptions (ObjC or C++), and mach exceptions. These are all very different things.

On iOS (and tvOS, macOS) the events that terminate a process are mach exceptions. These are the low-level events that you can, in fact, intercept. When you see that EXC_ prefix, you know you're looking at a mach exception. I believe these are all defined in mach/exception.h.

Now, iOS has an interesting implementation where if there are no mach exception handlers, the OS translates the event into a unix signal. The signal function can be used to intercept these. Since EXC_BAD_ACCESS is not a unix signal, it is not a valid argument to the signal function. But, you can add handlers to those signals listed, and they will give you roughly the same information.

Mach exceptions are a significantly more powerful and safer mechanism for intercepting these kinds of events. Unfortunately, they also require a dramatically more complex handling system. Signals have all kinds of problems, but they are a lot easier to use.

I would be interested to know what you're trying to do, in case perhaps there's a better way of achieving what you are after.

Again, I'd avoid going down this road. It just isn't worth your time. It is challenging to get things working at all, and when you do, you'll be lulled into a false sense of security. You might even think things are working right, because the times your code goes completely wrong, you'll never know and you'll just get weird reports from users of random hangs from time to time.

How to catch EXC_BAD_ACCESS (code=1, address=0x00XXXXXX)?

You can refer the following links :

EXC_BAD_ACCESS automatic handling

Also look into this :

How to prevent EXC_BAD_ACCESS from crashing an app?

How do I run a function before my app crashes? iOS

You can use NSSetUncaughtExceptionHandler and signal to catch most errors.

I've flagged a dupe answer which should have more details and discusses some edge cases that won't be caught without additional effort.

I don't know if C# changes the equation too dramatically. I haven't experimented with Xamarin.

EXC_BAD_ACCESS error in Objective-C

How is the headsetOnHandler and headsetOffHandler properties declared?

If it is assign or retain, that is likely the source of your problem. Since they are blocks, it needs to be copy (even, in certain cases, under ARC). If they are atomic and retain, then your getter will call, effectively, [[block retain] autorelease] in the getter, which would explain your crash.

A bit of a long shot.

  • when you have a crash, always post the backtrace

  • when you know the line of code the crash is on, always post the variable declarations of any variables on that line

Note that ARC will change this behavior a bit, automatically handling the blocks in some cases, but -- IIRC -- you would still need to copy them in this case.

Why does this EXC_BAD_ACCESS happen with long long and not with int?

That's actually very annoying, but not so unexpected for those of us bought up in a pre-x86 world :-)

The only reason that comes to mind (and this is pure speculation) is that the compiler is "fixing" your code to ensure that the data types are aligned correctly but the sizeof/alignof mismatches are causing problems. I seem to recall that ARM6 architecture relaxed some of the rules for some data types but never got a good look at it because the decision was made to go with a different CPU.

(Update: this is actually controlled by a register setting (hence probably the software) so I guess even modern CPUs can still complain bitterly about the misalignments).

The first thing I would do would be to have a look at the generated assembly to see if the compiler is padding your short to align the next (actual) data type (that would be impressive) or (more likely) pre-padding the actual data type before writing it.

Secondly, find out what the actual alignment requirement are for the Cortex A8 which I think is the core used in the IPhone4.

Two possible solutions:

1/ You may have to cast each type into a char array and transfer the characters one at a time - this should hopefully avoid the alignment issues but may have a performance impact. Use of memcpy would probably be best since it will no doubt be coded to take advantage of the underlying CPU already (such as transferring four-byte chunks where possible with one-byte chunks at the start and end).

2/ For those data types that don't want to be put immediately after a short, add enough padding after that short to ensure they align correctly. For example, something like:

tmp += sizeof(unsigned short);
tmp = (tmp + sizeof(T)) % alignof(T);

which should advance tmp to the next properly aligned location before attempting to store the value.

You'll need to do the same reading it back later (I'm assuming the short is indicative of the data being stored so you can tell what data type it is).


Putting the final solution from OP in the answer for completeness (so people don't have to check the comments):

First, the assembly (on Xcode, Run menu > Debugger Display > Source and Disassembly) shows that the STMIA instruction is used when handling 8 bytes of data (i.e., long long), instead of the STR instruction.

Next, section "A3.2.1 Unaligned data access" of the "ARM Architecture Reference Manual ARMv7-A" (the architecture corresponding to Cortex A8) states that STMIA does not support unaligned data access while STR does (depending on certain registry settings).

So, the problem was the size of long long and misalignment.

As for the solution, one-char-at-a-time is working, as a starter.

iOS EXC_BAD_ACCESS error

EXC_BAD_ACCESS errors occur when your application attempts to access an object that has already been released. If the issue happened after you converted the project to ARC, then somewhere there is a Zealous release call being made (on behalf of ARC). Try making sortedArray a strong property of your class, and set the variable as :

self.sortedArray = [array sortUsingDescriptor:...];

That must be it, because sortUsingDescriptor: probably returns an autoreleased object. In a non-arc project you'd have to encapsulate that call with a retain call:

[[array sortUsingDescriptor:...]retain];


Related Topics



Leave a reply



Submit