Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

UNIX Signal mistreated for communication suddenly receives from pid 0

$
0
0

I am doing a test setup where I use UNIX signals for communication.The following code uses SIGUSR1 and SIGUSR2 to transfer a string from a client process to a server process that will listen for incoming signals. I know this is not how signals should be used and I kindly ask you to disregard any "that function is not signal-safe", because in this test setup the client will wait for the server to acknowledge each received bit via a signal back to the client which will in turn as answer to that signal send the next bit to the server.This way no signal should interrupt while a signal is being handled. Or so I think at least... I am not sure on anything right now anymore...

The problem is that I suddenly receive signals from pid 0 (which is broadcast?) but I never send a broadcast. The code will work for smaller strings but getting larger (~100 chars) it will sometimes work and sometimes not. I could deal with this situation by just sending->sleep->sending in the client, which would be slower but I am really interested in what is going on here.

Here is the server code:

void    sig_handler(int _signum, siginfo_t *_info, void *_context){    static unsigned char    str[MAX_MSG_SIZE];    static int              str_i;    t_bool                  done;    int                     i;    if (_info->si_pid != 0)    {        if (((str_i++) * 0) || _signum == SIGUSR2)            str[(str_i - 1) / 8] |= 1 << (7 - (((str_i - 1) % 8)));        done = !(str_i % 8) && !str[(str_i / 8) - 1];        if (done)        {            i = ((str_i / 8 - 4) >= 0) * (str_i / 8 - 4)+ ((str_i / 8 - 4) < 0) * -1;//this saves a line...            while (++i < str_i / 8)                if (str[i] == 0xf0)                    done = FALSE;        }        if ((str_i / 8 == MAX_MSG_SIZE || done) && _info->si_pid != 0)        {            ft_printf("kill\n");            write(1, str, str_i / 8);            ft_memset(str, 0, MAX_MSG_SIZE);            str_i = 0;            kill(_info->si_pid, SIGUSR2);        }        else if (_info->si_pid != 0)            kill(_info->si_pid, SIGUSR1);        else ft_printf("wtf");    }    else ft_printf("\nOH WTF IS HAPPENING\n");}int main(void){    struct sigaction    sa;    ft_printf("%d\n", getpid());    sigemptyset(&sa.sa_mask);    sigaddset(&sa.sa_mask, SIGUSR1);    sigaddset(&sa.sa_mask, SIGUSR2);    sa.sa_sigaction = sig_handler;    sa.sa_flags = SA_RESTART | SA_SIGINFO;    if (sigaction(SIGUSR1, &sa, NULL) == -1        || sigaction(SIGUSR2, &sa, NULL) == -1)        return (0);    while (TRUE)        sleep(10000);    return (0);}

Notice i added allot of print statements to find out what is happening.here is the client:

typedef struct s_client_info{    int     pid;    char    *str;    int     i;    t_bool  run;}   t_client_info;void    sig_handler(int _signum, siginfo_t *_info, void *_context){    static t_client_info    *v;    //usleep(200);    if (_info  && !_info->si_pid) //this prints 0-n times randomly at any moment        ft_printf("wtf");    if (!_signum && !_info) //setup    {        v = _context;        v->run = TRUE;    }    if (_signum == SIGUSR2 || !v->run) //received stop signal from server    {        v->run = FALSE;        return ;    }    if (v->pid == 0) //is never called        ft_printf("Wtf1");    if ((v->str[v->i / 8] << (v->i % 8)) & 0b10000000) //extracts current bit        kill(v->pid, SIGUSR2); //send '1' to server    else        kill(v->pid, SIGUSR1); //send '0' to server    v->i++;}int main(int _argc, char *_argv[]){    t_client_info       v;    struct sigaction    sa;    int                 i;//check input    i = -1;    while (_argv[1][++i])        if (_argv[1][i] < '0' || _argv[1][i] > '9')            return (print_usage(), 0);    if (_argc != 3)        return (print_usage(), 0);//prepare client info    v.pid = ft_atoi(_argv[1]);    v.str = _argv[2];    v.i = 0;//register signal handler    sa.sa_flags = SA_SIGINFO;    sigemptyset(&sa.sa_mask);    sigaddset(&sa.sa_mask, SIGUSR1);    sigaddset(&sa.sa_mask, SIGUSR2);    sa.sa_sigaction = sig_handler;    if (sigaction(SIGUSR1, &sa, NULL) == -1        || sigaction(SIGUSR2, &sa, NULL) == -1)        return (0);//start sending    sig_handler(0, NULL, &v);    while (v.run)        usleep(10);    return (0);}

If I uncomment that usleep, the communication will work, but the client will still sometimes receive a signal from pid 0 and print "wtf"

I thought maybe another process is sending a broadcast randomly, so i set up an extra process that checks for that... nope there is no other process. somehow one of these or both end up sending a malformed signal.

This is some output from the server. After receiving the same message for a 3. time it will fail and never send the stop signal(SIGUSR2) to the client

😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuhkill😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh

OH WTF IS HAPPENING

I needed to stop the client manually at this point.

So I added this in the client and enabled the usleep again to check whether the weird pid = 0 signals come in at some specific time:

if ((v->str[v->i / 8] << (v->i % 8)) & 0b10000000)        ft_printf("1"),kill(v->pid, SIGUSR2);    else        ft_printf("0"),kill(v->pid, SIGUSR1);

And they just drop in randomly. here is an example:

./client 19863😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh😀wiegyhweoufgiaqefouhqaefouhqofsuh111100001001111110011000100000000111011101101001011001010110011101111001011010000111011101100101011011110111010101100110011001110110100101100001011100010110010101100110011011110111010101101000011100010110000101100101011001100110111101110101011010000111000101101111011001100111001101110101011010001111000010011111100110001000000001110111011010010110010101100111011110010110100001110111011001010110111101110101011001100110011101101001011000010111000101100101011001100110111101110101011010000111000101100001011001010110011001101111011101010110100001110001011011110110011001110011011101010110100011110000100111111001100010000000011101110110100101100101011001110111100101101000011101110110010101101111011101010110011001100111011010010110000101110001011001010110011001101111011101010110100001110001011000010110010101100110011011110111010101101000011100010110111101100110011100110111010101101000111100001001111110011000100000000111011101101001011001010110011101111001011010000111011101100101011011110111010101100110011001110110100101100001011100010110010101100110011011110111010101101000011100010110000101100101011001100110111101110101011010000111000101101111011001100111001101110101011010001111000010011111100110001000000001110111011010010110010101100111011110010110100001110111011001010110111101110101011001100110011101101001011000010111000101100101011001100110111101110101011010000111000101100001011001010110011001101111011101010110100001110wtf00101101111011001100111001101110101011010001111000010011111100110001000000001110111011010010110010101100111011110010110100001110111011001010110111101110101011001100110011101101001011000010111000101100101011001100110111101110101011010000111000101100001011001010110011001101111011101010110100001110001011011110110011001110011011101010110100011110000100111111001100010000000011101110110100101100101011001110111100101101000011101110110010101101111011101010110011001100111011010010110000101110001011001010110011001101111011101010110100001110001011000010110010101100110011011110111010101101000011100010110111101100110011100110111010101101000111100001001111110011000100000000111011101101001011001010110011101111001011010000111011101100101011011110111010101100110011001110110100101100001011100010110010101100110011011110111010101101000011100010110000101100101011001100110111101110101011010000111000101101111011001100111001101110101011010001111000010011111100110001000000001110111011010010110010101100111011110010110100001110111011001010110111101110101011001100110011101101001011000010111000101100101011001100110111101110101011010000111000101100001011001010110011001101111011101010110100001110001011011110110011001110011011101010110100011110000100111111001100010000000011101110110100101100101011001110111100101101000011101110110010101101111011101010110011001100111011010010110000101110001011001010110011001101111011101010110100001110001011000010110010101100110011011110111010101101000011100010110111101100110011100110111010101101000111100001001111110011000100000000111011101101001011001010110011101111001011010000111011101100101011011110111010101100110011001110110100101100001011100010110010101100110011011110111010101101000011100010110000101100101011001100110111101110101011010000111000101101111011001100111001101110101011010001111000010011111100110001000000001110111011010010110010101100111011110010110100001110111011001010110111101110101011001100110011101101001011000010111000101100101011001100110111101110101011010000111000101100001011001010110011001101111011101010110100001110001011011110110011001110011011101010110100011110000100111111001100010000000011101110110100101100101011001110111100101101000011101110110010101101111011101010110011001100111011010010110000101110001011001010110011001101111011101010110100001110001011000010110010101100110011011110111010101101000011100010110111101100110011100110111010101101000111100001001111110011000100000000111011101101001011001010110011101111001011010000111011101100101011011110111010101100110011001110110100101100001011100010110010101100110011011110111010101101000011100010110000101100101011001100110111101110101011010000111000101101111011001100111001101110101011010001111000010011111100110001000000001110111011010010110010101100111011110010110100001110111011001010110wtf1111011101010110011001100111011010010110000101110001011001010110011001101111011101010110100001110001011000010110010101100110011011110111010101101000011100010110111101100110011100110111010101101000111100001001111110011000100000000111011101101001011001010110011101111001011010000111011101100101011011110111010101100110011001wtf1101101001011000010111000101100101011001100110111101110101011010000111000101100001011001010110011001101111011101010110100001110001011011110110011001110011011101010110100011110000100111111001100010000000011101110110100101100101011001110111100101101000011101110110010101101111011101010110011001100111011010010110000101110001011001010110011001101111011101010110100001110001011000010110010101100110011011110111010101101000011100010110111101100wtf11001110011011101010110100000000000

here is another screenshot of a run without the usleep in client:

Server left, Client right.After that I send a small message to the server without restarting it and it suddenly send an extremly large message out of nowhere. Pages of 0s and 1s with just ./client pid asd.This was the servers reaction:The topmost message was the last from the last image

Does anyone have an idea what is happening?I thought by always reacting to a signal i should not go into any race condition but this behavior is just over my head.

UPDATE:

I used tried using the solution in the related question dimich commented (SIGINFO's si_pid sets itself to 0 after a few calls of the same function)I saved the pid to a static variable in the server and the communication suddenly works without usleep. HOWEVER the client still receives signals with _info->si_pid == 0. And even more interresting: the server sends those 100%. They are ack's the server sends. if i filter them out the client will hang waiting for an ack. I am also on Mac btw.


Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>