[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] problem with signals (SIGIO) in the petalinux-2.6.2 kernel



Hi !
I'm trying to implement a signal handler for the SIGIO signal in the user space.. The  singal is caught successfully with the signal handler. The problem is when the singal handler reaches the "return" point, it completely crashes the whole system !!

I traced the program using microblaze-uclinux-gdb and followed step by step what happens after the call to "return" in the signal handler, simply it goes into the address area of the process *stack* ... it then continues exceution from there !! just executing some "garbage" instructions in the stack untill a total system crash happens.

Is it normal for the signal handler to return into the stack ??
Please note that the very same attached code works very well on my desktop linux (i386) with NO problems!!



Get your own web address.
Have a HUGE year through Yahoo! Small Business.
#include <signal.h>
#include <stdio.h>

/*for fcntl()*/
#include <unistd.h> 
/*for fcntl()*/
#include <fcntl.h>

/*for getpid()*/
#include <sys/types.h>
/*for getpid()*/
#include <unistd.h>

/*for pthreads*/
#include <pthread.h>

/*for memset()*/
#include <string.h>

/*mutex is short for MUTual EXclusion*/
pthread_mutex_t dum_mutex = PTHREAD_MUTEX_INITIALIZER;

typedef void (*sighandler_t)(int);

void sighnd(int sig)
{
	struct sigaction sa;
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = &sighnd;
	int ret = sigaction(SIGIO, &sa, NULL);
	
	/* try to lock the dummy mutex to prevent any other threads of this handler to run before the current one finishes */
	int i = pthread_mutex_lock (&dum_mutex);
	
	if(!ret)
		printf("\n\nRe-registered the signal handler just in case linux resets it, registeration result: %d", ret);
	printf("\n\nHandler caught interrupt signal SIGIO");
	fflush(stdout);
	/*unlock the dummy mutex*/
	pthread_mutex_unlock (&dum_mutex);
	return;
}

int main(void)
{

struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &sighnd;
int ret = sigaction(SIGIO, &sa, NULL);

/*sighandler_t ret = signal(SIGIO, &sighnd);*/

if(!ret)
	printf("\n\nRegistered a handler to signal!\nWaiting for interrupts...");

//wait for signals from the kernel
for(;;)
	pause();//this function returns only when the signal handler returns

return 0;

}
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>


int main(void)
{
	int i;
	//the signal chld doesn't kill other processes
	i = kill(50, SIGIO);
	i = kill(51, SIGIO);
	i = kill(52, SIGIO);
	i = kill(53, SIGIO);

	//printf("\n\n%i\n\n", i);

}