views:

52

answers:

1

I suspect I am doing something dumb here but I am getting seg faults on an embedded Linux platform (GCC compiler) when I try to run pthread_rwlock_init() on a rwlock embedded in a structure.

struct rwlock_flag {
    int flag;           // Flag
    pthread_rwlock_t * rwlock;  // Reader/writer lock for flag
};

The following causes a seg fault...

struct rwlock_flag * running;
running = (struct rwlock_flag *) malloc (sizeof(struct rwlock_flag));
rslt = pthread_rwlock_init(running->rwlock, NULL);

As does this...

pthread_rwlock_t * rwlock_dg2;
pthread_rwlock_init(rwlock_dg2,NULL);

However the following works fine...

pthread_rwlock_t rwlock_dg;
pthread_rwlock_init(& rwlock_dg,NULL);

Any thoughts?

+7  A: 

Your first and second cases both try to initialise the rwlock for a pointer that points nowhere (well, technically, to a random or NULL location).

In the first case, you allocate space for your wrapper structure but not the pthread_rwlock_t* within it. Hence it would point to a random location.

This would work with an actual pthread_rwlock_t rather than a pointer to one:

struct rwlock_flag {
    int flag;                 // Flag
    pthread_rwlock_t rwlock;  // Reader/writer lock for flag
};
struct rwlock_flag * running;
running = (struct rwlock_flag *) malloc (sizeof(struct rwlock_flag));
rslt = pthread_rwlock_init(&(running->rwlock), NULL);

In the second, similarly, there's no backing storage for rwlock_dg2 so it either points to a random location (if allocated within a function) or NULL (if declared at file level). You need:

pthread_rwlock_t * rwlock_dg2 = malloc (sizeof (pthread_rwlock_t));
pthread_rwlock_init(rwlock_dg2,NULL);

Your third case, which works, does so because the pointer &rwlock_dg actually points to a real pthread_rwlock_t (which is of course rwlock_dg).

paxdiablo
caf
paxdiablo
Ahhhh! I assumed pthread_rwlock_init did its own malloc internally, thanks for your help
KermitG
Digging a bit deeper I think I was misslead by the man page for pthread_rwlock_init() which states "The pthread_rwlock_init() function shall allocate any resources required to use the read-write lock referenced by rwlock and initializes the lock to an unlocked"
KermitG
Actually, that's very subtle. It actually means any _other_ resources needed since "to use the read-write lock referenced by rwlock" means you must already have the reference in place (backing storage for the pointer). Sounds like the docs could be improved a little.
paxdiablo