problem with signals

This is a discussion on problem with signals within the C Programming forums, part of the General Programming Boards category; Hi, I'm experiencing a problem with signals between two processes. One process registers two simple signal handlers and runs an ...

  1. #1
    Registered User
    Join Date
    Mar 2007
    Posts
    12

    problem with signals

    Hi,

    I'm experiencing a problem with signals between two processes. One process registers two simple signal handlers and runs an infinite loop. The other sends it a SIGUSR1 to pause it, runs a bit of code, and then sends SIGUSR2 to awaken it. Thus far it works fine.

    However, if you try to run the sending process a second time while the first is still running, the looping process will quit instead of pausing and resuming again.

    Any idea what's wrong?

    Here's the code... note the sending process has to run with an argument which is the pid of the looping process.

    handler.c

    Code:
    #include <stdio.h>
    #include <signal.h>
    
    void hpause(int signo)
    {
      pause();
    }
    
    void hresume(int signo)
    {
    
    }
    
    int main(int argc, char ** argv)
    {
      signal(SIGUSR1, hpause);
      signal(SIGUSR2, hresume);
      
      while (1)
        printf("1 ");
    }
    pause.c
    Code:
    #include <stdio.h>
    #include <signal.h>
    
    #define OTHERPROCES atoi(argv[i])
    
    int main(int argc, char ** argv)
    {
      int i = 0;
      kill(OTHERPROCESS, SIGUSR1);
      
      for (i = 0; i < 100000; i++)
        printf("a b c d e f g ");
    
      kill(OTHERPROCESS, SIGUSR2);
    }

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,546
    http://www.cs.usyd.edu.au/cgi-bin/ma...pic=attributes
    Scroll down to Async-Signal-Safe
    If you're calling anything which is not on the safe list, then your code is broken.

    But that list is for Solaris. You need to find the equivalent list for your operating system.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User
    Join Date
    Mar 2007
    Posts
    12
    Yes I am working on Solaris.

    According to the link you gave me, the code should be ok... only pause() is used in the signal handler and it is in the safe list. So I guess it must be something else.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    A spelling error?

    Code:
    #define OTHERPROCES atoi(argv[i])
    
    int main(int argc, char ** argv)
    {
      int i = 0;
      kill(OTHERPROCESS, SIGUSR1);
      
      for (i = 0; i < 100000; i++)
        printf("a b c d e f g ");
    
      kill(OTHERPROCESS, SIGUSR2);
    }

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Assuming that is just a spelling error, look at this:
    Code:
    #include <stdio.h>
    #include <signal.h>
    
    #define OTHERPROCES atoi(argv[i])
    
    int main(int argc, char ** argv)
    {
      int i = 0;
      kill(OTHERPROCESS, SIGUSR1);
      
      for (i = 0; i < 100000; i++)
        printf("a b c d e f g ");
    
      kill(OTHERPROCESS, SIGUSR2);
    }
    First you call atoi(argv[0]), which unless your program name resembles a number, will probably return zero. I don't think you can kill the process with PID 0, and why you'd want to anyway.

    Secondly, you call atoi(argv[100000]), which is surely out of bounds; if it isn't, check to make sure it isn't.

    I'm guessing you meant
    Code:
    #define OTHERPROCES atoi(argv[1])
    or something.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Location
    Malta
    Posts
    9
    Hi, I'm working on this signals problem with cnchybrid. The code he pasted must have been an old, flawed version. This is the latest version of pause.c:

    Code:
    #include <stdio.h>
    #include <signal.h>
    
    #define OTHERPROCESS atoi(argv[1])
    
    int main(int argc, char ** argv)
    {
      int i = 0;
      printf("Sending SIGUSR1 to %d\n", OTHERPROCESS);
      kill(OTHERPROCESS, SIGUSR1);
      printf("Sent SIGUSR1\n");
      
      for (i = 0; i < 100000; i++)
        printf("a b c d e f g ");
    
      printf("Sending SIGUSR2\n");
      kill(OTHERPROCESS, SIGUSR2);
      printf("Sent SIGUSR2\n");
    }
    I can assure you that the latest version of our code works as described... the signals are sent, but pausing a second time terminates the looping process.

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,546
    http://www.opengroup.org/onlinepubs/...sigaction.html
    Perhaps your signal handlers are being reset to default behaviour (ie, exit) after being triggered for the first time.
    If you want the signal handler to persist, you need some additional stuff.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    Registered User
    Join Date
    Apr 2007
    Location
    Malta
    Posts
    9
    Thanks for your help. I didn't really understand how those signal sets and masks and stuff work, but I still followed the hint that signal handlers are being reset to default behaviour, and I made a signal handler reset them to required behaviour.

    Code:
    void hresume(int signo)
    {
      signal(SIGUSR1, hpause);
      signal(SIGUSR2, hresume);
    }
    This solved the problem. Is it a good solution or can there be consequences I'm not considering? For example, if the process is paused and receives a non-SIGUSR2 signal, will the signal be lost or will it remain pending and be handled when the process resumes?

    If it's a bad solution, can you suggest alternatives? (I'm guessing I have to use those sigsets)

  9. #9
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,546
    Signals are not queued, so at high rates, losing them is a real possibility.

    Using sigaction seems a much better idea, plus you need to enhance your handlers to take into account the possibility of missed signals.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  4. Problem with signals
    By kahad in forum C Programming
    Replies: 9
    Last Post: 12-07-2006, 09:42 AM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 04:46 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21