pitfalls of signals

Discussion in 'C Programming' started by Mantorok Redgormor, Oct 31, 2003.

  1. Should I just avoid them?
    I have heard many bad things about them
    1) if you set a signal handler, you can't really ignore the signal and
    continue with normal program execution, because after that undefined
    behavior is invoked.

    2) if you have a signal handler set for say SIG_INT and you continue
    to reset the handler after you received the signal, to continue normal
    program execution, and the signal is received twice or something you
    end up invoking undefined behavior and re-entry of a signal handler
    function causing major problems

    what are some other things i should be aware of for signals?

    and what should i do about points 1 and 2?

    there really is no alternative to a portable function like signal but
    signal itself seems to be a hazardous piece of crap
     
    Mantorok Redgormor, Oct 31, 2003
    #1
    1. Advertising

  2. In article <>,
    Mantorok Redgormor <> wrote:
    >Should I just avoid them?
    >I have heard many bad things about them
    >1) if you set a signal handler, you can't really ignore the signal and
    >continue with normal program execution, because after that undefined
    >behavior is invoked.


    This is not universally true and, in the cases where it is true, is a
    red herring.

    If you have a signal handler that was invoked as a result of your program
    calling raise(), then the signal is handled in a well-defined manner and
    you can continue your program exactly the same way as if you had just
    called the signal handler directly (unless you call raise() or abort()
    in the signal handler; in that case you've invoked undefined behavior
    before the normal program execution continues (N869 7.14.1.1#4)).

    If a signal handler is invoked asynchronously because of an external event
    unrelated to a computational exception, then normal program execution
    continues after the handler returns, without invoking undefined behavior
    (unless you've invoked undefined behavior in the handler by calling a
    library function other than the ones you're specifically permitted to
    call) (N869 7.14.1.1#3).

    If a signal handler is invoked because of a computational exception, the
    program has already invoked undefined behavior (f'rexample, by dividing
    by zero or dereferencing a bad pointer) (N869 7.14.1.1#3); the signal
    handler is your chance to clean up some things and terminate somewhat less
    ungracefully (which, unless you can do it without calling any library
    functions, invokes more undefined behavior), or possibly fix the cause
    of the error (the way to do that will be completely system-specific),
    also invoking undefined behavior.

    So the only way undefined behavior can be invoked by a signal handler
    ignoring the cause of the signal and returning (allowing the program to
    continue) is if the signal was raised because something in the program
    already invoked undefined behavior.


    >2) if you have a signal handler set for say SIG_INT and you continue
    >to reset the handler after you received the signal, to continue normal
    >program execution, and the signal is received twice or something you
    >end up invoking undefined behavior and re-entry of a signal handler
    >function causing major problems


    I'm not quite sure what you're trying to say here, but if you're worried
    about the signal handler getting re-invoked because a signal is raised
    before the handler finishes, I don't think that's a problem.
    Implementations are allowed to do one of two things to deal with this:
    -Temporarily block a set of signals that includes the one the handler
    is dealing with until the handler finishes. In this case the signal
    handler cannot be re-entered as a result of another signal being
    received, so there is no problem.
    -Reset the handler for that signal to SIG_DFL before invoking the handler.
    In this case, the user-defined handler will not be re-entered unless
    the handler reinstates itself for that signal. If the handler does
    things that shouldn't be done in overlapping calls, then just don't
    reinstate the signal until those things are complete. Since a signal
    handler is explicitly permitted to reinstate itself (N869 7.14.1.1#5),
    the implementation is responsible for making sure that nothing invokes
    undefined behavior by stepping on its toes after it's done so.


    >what are some other things i should be aware of for signals?


    The standard specification of signal handling (section 7.14 in N869 (and
    I assume C99 as well), or its equivalent in C90), plus the platform's
    specification of signal handling for every platform you're supporting.


    >and what should i do about points 1 and 2?


    Understand them well enough to know better than to worry about them.


    >there really is no alternative to a portable function like signal but
    >signal itself seems to be a hazardous piece of crap


    The portable parts aren't dangerous, and the dangerous parts aren't
    portable, so I don't see a problem here.

    signal itself really isn't as portable as it looks; all it does is provide
    a portable way to hook into system-specific behavior (like computational
    exceptions and external interruptions) or know that the implementation
    doesn't support it.

    It's perfectly valid for signal() to always return SIG_ERR, which will
    make it pretty much useless for anything you wanted to do with it.


    dave

    --
    Dave Vandervies
    Therefore using Venn diagrams, I own the only cardboard box on the web,
    which has its own set of software drivers.
    --Chris Hacking in the scary devil monastery
     
    Dave Vandervies, Oct 31, 2003
    #2
    1. Advertising

  3. (Dave Vandervies) wrote in message news:<bnu4dh$ik5$>...
    > In article <>,
    > Mantorok Redgormor <> wrote:
    > >Should I just avoid them?
    > >I have heard many bad things about them
    > >1) if you set a signal handler, you can't really ignore the signal and
    > >continue with normal program execution, because after that undefined
    > >behavior is invoked.

    >
    > This is not universally true and, in the cases where it is true, is a
    > red herring.
    >
    > If you have a signal handler that was invoked as a result of your program
    > calling raise(), then the signal is handled in a well-defined manner and
    > you can continue your program exactly the same way as if you had just
    > called the signal handler directly (unless you call raise() or abort()
    > in the signal handler; in that case you've invoked undefined behavior
    > before the normal program execution continues (N869 7.14.1.1#4)).
    >
    > If a signal handler is invoked asynchronously because of an external event
    > unrelated to a computational exception, then normal program execution
    > continues after the handler returns, without invoking undefined behavior
    > (unless you've invoked undefined behavior in the handler by calling a
    > library function other than the ones you're specifically permitted to
    > call) (N869 7.14.1.1#3).
    >
    > If a signal handler is invoked because of a computational exception, the
    > program has already invoked undefined behavior (f'rexample, by dividing
    > by zero or dereferencing a bad pointer) (N869 7.14.1.1#3); the signal
    > handler is your chance to clean up some things and terminate somewhat less
    > ungracefully (which, unless you can do it without calling any library
    > functions, invokes more undefined behavior), or possibly fix the cause
    > of the error (the way to do that will be completely system-specific),
    > also invoking undefined behavior.
    >
    > So the only way undefined behavior can be invoked by a signal handler
    > ignoring the cause of the signal and returning (allowing the program to
    > continue) is if the signal was raised because something in the program
    > already invoked undefined behavior.
    >
    >
    > >2) if you have a signal handler set for say SIG_INT and you continue
    > >to reset the handler after you received the signal, to continue normal
    > >program execution, and the signal is received twice or something you
    > >end up invoking undefined behavior and re-entry of a signal handler
    > >function causing major problems

    >
    > I'm not quite sure what you're trying to say here, but if you're worried
    > about the signal handler getting re-invoked because a signal is raised
    > before the handler finishes, I don't think that's a problem.
    > Implementations are allowed to do one of two things to deal with this:
    > -Temporarily block a set of signals that includes the one the handler
    > is dealing with until the handler finishes. In this case the signal
    > handler cannot be re-entered as a result of another signal being
    > received, so there is no problem.
    > -Reset the handler for that signal to SIG_DFL before invoking the handler.
    > In this case, the user-defined handler will not be re-entered unless
    > the handler reinstates itself for that signal. If the handler does
    > things that shouldn't be done in overlapping calls, then just don't
    > reinstate the signal until those things are complete. Since a signal
    > handler is explicitly permitted to reinstate itself (N869 7.14.1.1#5),
    > the implementation is responsible for making sure that nothing invokes
    > undefined behavior by stepping on its toes after it's done so.
    >


    Well this explains it: http://razor.bindview.com/publish/papers/signals.html


    >
    > >what are some other things i should be aware of for signals?

    >
    > The standard specification of signal handling (section 7.14 in N869 (and
    > I assume C99 as well), or its equivalent in C90), plus the platform's
    > specification of signal handling for every platform you're supporting.
    >
    >
    > >and what should i do about points 1 and 2?

    >
    > Understand them well enough to know better than to worry about them.
    >
    >
    > >there really is no alternative to a portable function like signal but
    > >signal itself seems to be a hazardous piece of crap

    >
    > The portable parts aren't dangerous, and the dangerous parts aren't
    > portable, so I don't see a problem here.
    >
    > signal itself really isn't as portable as it looks; all it does is provide
    > a portable way to hook into system-specific behavior (like computational
    > exceptions and external interruptions) or know that the implementation
    > doesn't support it.
    >
    > It's perfectly valid for signal() to always return SIG_ERR, which will
    > make it pretty much useless for anything you wanted to do with it.
    >
    >
    > dave


    - nethlek
     
    Mantorok Redgormor, Nov 2, 2003
    #3
  4. In article <>,
    Mantorok Redgormor <> wrote:
    > (Dave Vandervies) wrote in message
    >news:<bnu4dh$ik5$>...
    >> In article <>,
    >> Mantorok Redgormor <> wrote:
    >> >Should I just avoid them?
    >> >I have heard many bad things about them
    >> >1) if you set a signal handler, you can't really ignore the signal and
    >> >continue with normal program execution, because after that undefined
    >> >behavior is invoked.

    >>
    >> This is not universally true and, in the cases where it is true, is a
    >> red herring.


    <snip detailed explanation>

    >> >2) if you have a signal handler set for say SIG_INT and you continue
    >> >to reset the handler after you received the signal, to continue normal
    >> >program execution, and the signal is received twice or something you
    >> >end up invoking undefined behavior and re-entry of a signal handler
    >> >function causing major problems

    >>
    >> I'm not quite sure what you're trying to say here, but if you're worried
    >> about the signal handler getting re-invoked because a signal is raised
    >> before the handler finishes, I don't think that's a problem.


    <snip another detailed explanation>

    >Well this explains it: http://razor.bindview.com/publish/papers/signals.html


    This looks pretty unix-specific to me, so comp.unix.programmer would
    probably be a better place to discuss specific problems related to it
    than comp.lang.c .

    It seems to me, though, that all of the problems noted there are caused
    by asynchronous signal handlers doing things that are specifically stated
    to cause undefined behavior if done in an asynchronous signal handler,
    so saying that signals are unsafe because of this is a lot like saying
    that dynamic memory allocation is unsafe because using a pointer that's
    been freed invokes undefined behavior. The correct solution is to be
    aware of the restrictions that need to be observed and to be careful
    (or to use constructs that are harder to do dangerous things with if
    you're unwilling or unable to do so).


    dave

    --
    Dave Vandervies
    If his homework involves writing DOS programs, he probably needs all the
    help he can get.
    --Richard Heathfield in comp.lang.c
     
    Dave Vandervies, Nov 2, 2003
    #4
  5. Mantorok Redgormor

    Villy Kruse Guest

    On Fri, 31 Oct 2003 16:59:29 +0000 (UTC),
    Dave Vandervies <> wrote:


    >
    >I'm not quite sure what you're trying to say here, but if you're worried
    >about the signal handler getting re-invoked because a signal is raised
    >before the handler finishes, I don't think that's a problem.
    >Implementations are allowed to do one of two things to deal with this:
    >-Temporarily block a set of signals that includes the one the handler
    > is dealing with until the handler finishes. In this case the signal
    > handler cannot be re-entered as a result of another signal being
    > received, so there is no problem.
    >-Reset the handler for that signal to SIG_DFL before invoking the handler.
    > In this case, the user-defined handler will not be re-entered unless
    > the handler reinstates itself for that signal. If the handler does
    > things that shouldn't be done in overlapping calls, then just don't
    > reinstate the signal until those things are complete. Since a signal
    > handler is explicitly permitted to reinstate itself (N869 7.14.1.1#5),
    > the implementation is responsible for making sure that nothing invokes
    > undefined behavior by stepping on its toes after it's done so.
    >



    The end result will be quite different. When a new signal arrives while
    the handler is set to SIG_DFL the result can be quite catastrofic for
    the process, considering the normal action of SIG_DFL is to terminate
    the process.


    Villy
     
    Villy Kruse, Nov 4, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. spamfurnace
    Replies:
    1
    Views:
    405
    Alvin Bruney [MVP]
    May 24, 2004
  2. Carlos
    Replies:
    1
    Views:
    593
    Carlos
    Nov 7, 2005
  3. =?Utf-8?B?dmE=?=

    ASP.NET Profile Provider benefits and pitfalls?

    =?Utf-8?B?dmE=?=, Mar 24, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    576
    =?Utf-8?B?dmE=?=
    Mar 24, 2006
  4. Juan T. Llibre
    Replies:
    9
    Views:
    416
    Juan T. Llibre
    Jul 11, 2006
  5. Geoffrey
    Replies:
    2
    Views:
    350
    Geoffrey
    Jul 7, 2004
Loading...

Share This Page