signal handling [Archive] - C Board

PDA

View Full Version : signal handling


quagsire
07-11-2002, 07:13 AM
My program keeps on receiving signals. It cause the program to fall over. Is there any way to check where the signals originate from (pid ?). I do not want to block the signals as that is only a workaround, and just handling the signals do not work either. I receive signal 20 (SIGCHLD), but the process have got no children.

shaik786
07-11-2002, 07:35 AM
What OS? If it's UNIX (XPG4), Try using the sigaction() function instead of signal(), which will give you more idea of the signal.

quagsire
07-11-2002, 08:05 AM
I am using IBM AIX v4.3.3.0.

shaik786
07-11-2002, 11:41 PM
As i already said, if you are using signal() in your code, replace your signal() function with sigaction() [supported in AIX 4.3]. This will clearly tell you what the signal was and where the signal came from.

quagsire
07-12-2002, 02:20 AM
I am using the following :


void sigchld_handler(int s)
{

}

int main()
{
struct sigaction sa;

sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGCHLD, &sa, NULL) == -1)
{
perror("sigaction");
exit(1);
}
/* ... Lots of code ... */
}


How do I get the pid from the process that sends the signal when I am in the signal handler ?

shaik786
07-12-2002, 04:10 AM
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sig_handler(int signo, siginfo_t *info, void *context);
int main(void);

void sig_handler(int signo, siginfo_t *info, void *context)
{
if(info) {
printf(" SIGNAL (number) : %d\n", info->si_signo);
printf(" SIGNAL (pid ) : %d\n", info->si_pid);
}
}

int main(void)
{
struct sigaction new_action, old_action;

new_action.sa_sigaction = sig_handler;
new_action.sa_flags = SA_SIGINFO;
sigemptyset(&new_action.sa_mask);

if(sigaction(SIGUSR1, &new_action, &old_action) == -1) {
perror(" sigaction");
exit(-1);
}

pause();

return(0);
}


Make sure the structure members of type 'struct sigaction' i've used here are supported in your AIX version too. I've tested the above program in Digital 4.0, and works perfect.
In function sig_handler(), the member info->si_pid is the PID of the process which signalled and info->si_signo is the signal number it signalled.

quagsire
07-12-2002, 05:54 AM
I have tried what you suggested :

void sttSignalHandler(int signo, siginfo_t *info, void *context)
{
if (info)
{
cout << "[" << getpid() << "] Received signal " << info->si_signo
<< " from pid " << info->si_pid << ". si_errno : " << info->si_errno
<< " si_code : " << info->si_code
<< " si_uid : " << info->si_uid
<< " si_status : " << info->si_status
<< endl;
}
}

void main(void)
{
struct sigaction new_action, old_action;

new_action.sa_sigaction = sttSignalHandler;
new_action.sa_flags = SA_SIGINFO;

if(sigaction(SIGCHLD, &new_action, &old_action) == -1) {
perror(" sigaction");
exit(-1);
}
/* Lots of code */
}


Here is the output :
[190560] Received signal 537348952 from pid 536954544. si_errno : 537408136 si_code : 0 si_uid : 536954556 si_status : 536954580


When run on a different box (also IBM:AIX 4.3.3.0), it gives me the correct values :
[148194] Received signal 20 from pid 65312. si_errno : 0 si_code : 8 si_uid : 534 si_status : 0

Any ideas ?

shaik786
07-12-2002, 06:24 AM
Read the manual page on sigaction on each box. That should give you an idea what went wrong. Mine say's when si_errno is not equal to 0, some error occured.

quagsire
07-18-2002, 03:31 AM
I found the problem. When connecting directly to oracle, it is seen as a child process of the application. When a logoff is done, it sends a signal 20 because the "child" died. By talking to a listener and not directly to oracle, the problem was solved.