Showing posts with label pthread. Show all posts
Showing posts with label pthread. Show all posts

Thursday, March 08, 2012

iOS device: EXC_BAD_ACCESS error with EXC_ARM_DA_ALIGN code

I spent a day hunting down one nasty bug in my code.
This code worked fine on Android ARM7 build, iPhone simulator (i386) build,
but started to crash once I run it on iPhone 4 device.

The code was implementing simple wrappers for the mutex, the event and the thread API.

For example the mutex handle looked something like this:

typedef struct _MUTEX_HANDLE {
    .........
    pthread_mutex_t mutex;
} MUTEX_HANDLE;

Then the event and thread structures where built upon this.

The problem only surfaced on iOS device, with error EXC_BAD_ACCESS and the code EXC_ARM_DA_ALIGN. I checked and double checked all the structures in memory their alignment etc., and still could not see anything wrong.  I searched online and got distracted with many articles reporting the similar type of problem and suggesting memcpy as a solution in order to "fix" this alignment issue.

The definitions of the pthread handles though was kind of curious:
struct _opaque_pthread_mutex_t { long __sig; char __opaque[__PTHREAD_MUTEX_SIZE__]; };
in addition to the signal handle there was an array.

Eventually I narrowed this down to the simple assignment by value where I just initialized 
pthread_mutex_t variable and assigned it by value to my structure member.

static int createMutex(MUTEX_HANDLE **pHandle) {
    pthread_mutex_t mtx;
    int err = initMutex(&mtx);
    if (!err) { 
        MUTEX_HANDLE *ph = malloc(sizeof(MUTEX_HANDLE));
        if (ph) {
           ph->mutex = mtx; //the problem is here, never do this!!! 

The pthread_mutex_t type is very simple structure on Android with one int member, so I kind of assumed that assigning pthread_mutex_t by value would not incur that much overhead or side effects and just did what I did above. So, this was not the best decision on my part.

The fix was to eliminate the temporary pthread_mutex_t variable on a stack and use the mutex member of the MUTEX_HANDLE structure directly: 

static int createMutex(MUTEX_HANDLE **pHandle) {
    MUTEX_HANDLE *ph = malloc(sizeof(MUTEX_HANDLE));
    if (ph) {
        int err = initMutex(&ph->mutex);

So, the EXC_ARM_DA_ALIGN error was just a big distraction that had me wasting quite a bit of time looking in the wrong direction.