Subject: lib/20607: pthread_mutex gives a core dump, can't be traced with gdb
To: None <gnats-bugs@gnats.netbsd.org>
From: None <htodd@twofifty.com>
List: netbsd-bugs
Date: 03/06/2003 17:18:35
>Number:         20607
>Category:       lib
>Synopsis:       pthread_mutex gives coredump, can't be traced with gdb
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 06 17:19:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD 1.6P-20030306
>Organization:
Hisashi T Fujinaka - htodd@twofifty.com
BSEE (6/86) + BSChem (3/95) + BAEnglish (8/95) + $2.50 = mocha latte
>Environment:
	
	
System: NetBSD allison 1.6P NetBSD 1.6P (ALLISON) #215: Thu Mar 6 08:57:59 PST 2003 htodd@allison:/disk/0/obj/sys/arch/i386/compile/ALLISON i386
Architecture: i386
Machine: i386
>Description:
I am including the source code that I am compiling with -g -lpthread. It dumps core, but there's no debugging symbols in the core file. There are probably errors in my code, but I'm unable to use my regular debugging methods to find them.
	
>How-To-Repeat:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

#define SEMPATH "/tmp/htodd_pc"
#define BUFSZ 200
#define SEMKEY 4004
#define SHMKEY 4104

/* union decl from semctl man page */
union semun {
	int val;
	struct semid_ds *buf;
	ushort *array;
};

struct sembuf Pe = {0, -1, 0};
struct sembuf Ve = {0, 1, 0};
struct sembuf Pf = {1, -1, 0};
struct sembuf Vf = {1, 1, 0};

/* from client stuff */

#define MAXSHM 200
#define NUMSHM 12

typedef struct {
	key_t key;
	int shmid;
} keypair;

keypair * shm_array[MAXSHM];

/* all_shm is a copy of the shared memory segments in case we have to clean up */
keypair * all_shm[MAXSHM];

/* functions */
void cleanup(int signo);

int putshm(pthread_mutex_t * memlock, keypair ** shm_array, keypair * keys) {
	int index;
	
	if (pthread_mutex_lock(memlock) != 0) {
		perror("locking shm mutex");
		return 0;
	}

  index = (int)shm_array[0] + 1;
	shm_array[index]->key = keys->key;
	shm_array[index]->shmid = keys->shmid;
	shm_array[0] = (void *)index;
	free(keys);

	if (pthread_mutex_unlock(memlock) != 0) {
		perror("unlocking mutex");
		return 0;
	}
	return 1;
}

keypair * getshm(pthread_mutex_t * memlock, keypair ** shm_array) {
	keypair * retval;
	int index;

	if (pthread_mutex_lock(memlock) != 0) {
		perror("locking shm mutex");
		return NULL;
	}
	index = (int)shm_array[0];

	if (index < 1) {
		retval = NULL;
	} else {
		shm_array[0] = (void *)(index - 1);
		retval = (keypair *)calloc((size_t)sizeof(keypair), (size_t) 2);
		retval->key = shm_array[index]->key;
		retval->shmid = shm_array[index]->shmid;
	}

	if (pthread_mutex_unlock(memlock) != 0) {
		perror("unlocking mutex");
		exit(EXIT_FAILURE);
	}
	return retval;
}


void delsharedmem(keypair ** shm_array, int count) {
	int i;

	for (i = 1; i <= count; ++i) {
		if (shm_array[i] != NULL) {
			if (shmctl((*shm_array[i]).shmid, IPC_RMID, NULL) == -1) {
				perror("closing shared memory");
			}
//			printf("%i key: %i, shmid: %i\n", i, (*shm_array[i]).key, (*shm_array[i]).shmid);
			free(shm_array[i]);
		}
	}
}
	
int makesharedmem(keypair ** shm_array, int count) {
	keypair * memtuple;
	int shm_id, i, j = 0;

	for (i = 1; i <= count; ++i) {
		/* create the shared memory */
		if ((shm_id = shmget((SHMKEY + i*100), (size_t)(BUFSZ + 1), 0666|IPC_CREAT))
				== -1) {
			perror("getting shared memory array");
		} else {
			++j;
			memtuple = (keypair *)calloc((size_t)sizeof(keypair), (size_t) 2);
			memtuple->key = SHMKEY + i;
			memtuple->shmid = shm_id;
			shm_array[j] = memtuple;
			all_shm[j] = memtuple;
//			printf("%i key: %i, shmid: %i\n", i, SHMKEY + i, shm_id);
		}
	}
	shm_array[0] = (void *)j;
	all_shm[0] = (void *)j;
	return j;
}

int main() {
	key_t key_key;
	int key_id, fd, i, spinval, memct;
	size_t key_size, shm_size;
	keypair * passkey;
	void *keyaddr, *memaddr;
	char filename[4];
	struct shmid_ds key_data;	/* shared mem result struct */
	struct shmid_ds shm_data;	/* shared mem result struct */
	pthread_mutexattr_t mattr;
	pthread_mutex_t shmmutex;

	key_key = SHMKEY;

	/* init mutex attributes and mutex */
	if (pthread_mutexattr_init(&mattr) != 0) {
		perror("initializing mutexattr");
		goto cleanup;;
	}
	if (pthread_mutex_init(&shmmutex, &mattr) != 0) {
		perror("initializing shmmutex");
		goto cleanup;;
	}

	/* create the shared memory */
	if ((key_id = shmget(key_key, (size_t)(BUFSZ + 1), 0666|IPC_CREAT)) == -1) {
		perror("getting shared key memory");
		goto cleanup;
	}

	printf("passing keys in shm_id: %u, shm_key: %u\n", key_id, key_key);

	/* attach the shared memory */
	if ((keyaddr = shmat(key_id, (void *)0, 0)) == (void *)(-1)) {
		perror("attaching memory");
		goto cleanup;
	}

	/* check to see how much shared memory we really got */
	if (shmctl(key_id, IPC_STAT, &key_data) == -1) {
		perror("getting shared memory stat");
		goto cleanup;
	}
	key_size = key_data.shm_segsz;


	/* if there's a size discrepancy, print it out */
	if (key_size != (BUFSZ + 1)) {
		printf("we only got: %i bytes\n", key_size);
	}

	bzero(keyaddr, (size_t)(key_size));

	/* get array of shared memory */
	if ((memct = makesharedmem(shm_array, NUMSHM)) == 0) {
		goto cleanup;
	}

	for (i = 1; i < 7; ++i) {
		/* wait for empty key buffer */
		while(((unsigned char *)keyaddr)[0] != 0);
		
		/* zero the key memory */
		bzero(keyaddr, (size_t)(shm_size));

		/* get some shared memory */
		do {
			passkey = getshm(&shmmutex, shm_array);
		} while (passkey == NULL);


		/* attach the shared memory */
		if ((memaddr = shmat(passkey->shmid, (void *)0, 0)) == (void *)(-1)) {
			perror("attaching memory");
		}
		
		printf("loop #: %i, key used is: %u\n", i, passkey->shmid);
		
		/* write the shared memory data to key mem */
		if (snprintf(&(((char *)keyaddr)[1]), (size_t)(key_size - 1), "%i", passkey->shmid) < 0) {
			perror("writing key data");
			goto cleanup;
		}

		/* check to see how much shared memory we really got */
		if (shmctl(passkey->shmid, IPC_STAT, &shm_data) == -1) {
			perror("getting shared memory stat");
		}
		shm_size = shm_data.shm_segsz;
		
		/* zero the memory */
		bzero(memaddr, (size_t)(shm_size));

		/* open the file to read */
		sprintf(filename, "in%i", i);
		if ((fd = open(filename, O_RDONLY)) == -1) {
			perror("opening file");
			goto cleanup;
		}

		if (read(fd, &(((unsigned char *)memaddr)[1]), (size_t)(shm_size - 1)) == -1) {
			perror("reading file");
			goto cleanup;
		}

		if (close(fd) == -1) {
			perror("closing file");
		}

		/* set full */
		((unsigned char *)keyaddr)[0] = 1;
	}

	/* wait for empty buffer */
	while(((unsigned char *)keyaddr)[0] != 0);

cleanup:
	/* close the shared memory */
	if (shmctl(key_id, IPC_RMID, NULL) == -1) {
		perror("closing shared memory");
	}
	delsharedmem(shm_array, NUMSHM);
	exit(EXIT_SUCCESS);
}

	
>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted: