How to handle SIGABRT without stopping the code - Unix

This is a discussion on How to handle SIGABRT without stopping the code - Unix ; Hi, I'm a newbie with signals and I need a little help. I have a program that does arithmetic operations among integers and I want to check when overflow happens. I found that in the last versions of gcc, compiling ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: How to handle SIGABRT without stopping the code

  1. How to handle SIGABRT without stopping the code

    Hi, I'm a newbie with signals and I need a little help.

    I have a program that does arithmetic operations among integers and I
    want to check when overflow happens.

    I found that in the last versions of gcc, compiling with option -
    ftrapv, when the code have to execute arithmetic operations, instead
    of using the normal routines, it uses routines in libc that check for
    overflow.

    If overflow happens on the screen you see "Aborted" and the code
    stops.

    My question is:

    Is it possible to have the message about overflow only but avoid that
    the program stops?

    In other words, if I understood correctly, how can I build a handler
    function that replaces the one usually used by the OS so that SIGABRT
    can be managed in a custom way?

    Searching the internet, I found that it is something related to the
    handler function but this topic is not so easy to manage for a newbie
    like me.

    TIA

    Daniele

  2. Re: How to handle SIGABRT without stopping the code

    arkkimede@gmail.com wrote:
    > Hi, I'm a newbie with signals and I need a little help.
    >
    > I have a program that does arithmetic operations among integers and I
    > want to check when overflow happens.
    >
    > I found that in the last versions of gcc, compiling with option -
    > ftrapv, when the code have to execute arithmetic operations, instead
    > of using the normal routines, it uses routines in libc that check for
    > overflow.
    >
    > If overflow happens on the screen you see "Aborted" and the code
    > stops.
    >
    > My question is:
    >
    > Is it possible to have the message about overflow only but avoid that
    > the program stops?
    >
    > In other words, if I understood correctly, how can I build a handler
    > function that replaces the one usually used by the OS so that SIGABRT
    > can be managed in a custom way?
    >
    > Searching the internet, I found that it is something related to the
    > handler function but this topic is not so easy to manage for a newbie
    > like me.


    man sigaction

    That function lets you set up your own signal handler.


    Bjarni
    --

    INFORMATION WANTS TO BE FREE

  3. Re: How to handle SIGABRT without stopping the code

    arkkimede@gmail.com writes:

    > Hi, I'm a newbie with signals and I need a little help.
    >
    > I have a program that does arithmetic operations among integers and I
    > want to check when overflow happens.
    >
    > I found that in the last versions of gcc, compiling with option -
    > ftrapv, when the code have to execute arithmetic operations, instead
    > of using the normal routines, it uses routines in libc that check for
    > overflow.
    >
    > If overflow happens on the screen you see "Aborted" and the code
    > stops.
    >
    > My question is:
    >
    > Is it possible to have the message about overflow only but avoid that
    > the program stops?


    Not really, AFAIK.

    > In other words, if I understood correctly, how can I build a handler
    > function that replaces the one usually used by the OS so that SIGABRT
    > can be managed in a custom way?


    You can write a handler for SIGABRT, and install it using the signal()
    function, but you won't be able to resume the operation that
    overflowed. The best you can do is to use longjmp() to return to a
    higher level of your program.

    If you're on Linux, a good source of information on these issues is the
    glibc manual (type "info libc"). It's also online at
    http://www.gnu.org/software/libc/man...ode/index.html . Even if
    you're not on Linux, most of what it says carries over to other
    Unix-like systems. Read the chapters on "Signal handling" and
    "Non-local exits". Then come back and ask if you have further
    questions.

  4. Re: How to handle SIGABRT without stopping the code

    On 1 Nov, 01:12, Nate Eldredge wrote:
    > arkkim...@gmail.com writes:
    > > Hi, I'm a newbie with signals and I need a little help.

    >
    > > I have a program that does arithmetic operations among integers and I
    > > want to check when overflow happens.

    >
    > > I found that in the last versions of gcc, compiling with option -
    > > ftrapv, when the code have to execute arithmetic operations, instead
    > > of using the normal routines, it uses routines in libc that check for
    > > overflow.

    >
    > > If overflow happens on the screen you see "Aborted" and the code
    > > stops.

    >
    > > My question is:

    >
    > > Is it possible to have the message about overflow only but avoid that
    > > the program stops?

    >
    > Not really, AFAIK. *
    >
    > > In other words, if I understood correctly, how can I build a handler
    > > function that replaces the one usually used by the OS so that SIGABRT
    > > can be managed *in a custom way?

    >
    > You can write a handler for SIGABRT, and install it using the signal()
    > function, but you won't be able to resume the operation that
    > overflowed. *The best you can do is to use longjmp() to return to a
    > higher level of your program.
    >
    > If you're on Linux, a good source of information on these issues is the
    > glibc manual (type "info libc"). *It's also online athttp://www.gnu.org/software/libc/manual/html_node/index.html. *Even if
    > you're not on Linux, most of what it says carries over to other
    > Unix-like systems. *Read the chapters on "Signal handling" and
    > "Non-local exits". *Then come back and ask if you have further
    > questions.


    I found a possible solution observing that in a child process generate
    by a fork, the signal SIGABRT can be managed by a handler function
    where you can do something.
    In the program the child process ends (on the screen does not appear
    ABORTED) then there is the execution of the father process etc.
    This is a "dirty" solution because it is not possible, after the
    overflow, to set any variable or flag for the father. I was
    erroneously thinking to set a global variable in the handler function
    so that the father, testing this variable, can understand the
    overflow. This is wrong because when the child process disappear, also
    the variable setting disappear so, for the father, nothing has
    occurred.
    The only thing that can survive to the child process is a file.
    For this reason in the handler function I write a empty file
    overflow.dat and the father verify the existence of this file to
    understand if overflow occurred.

    Comments are welcome



  5. Re: How to handle SIGABRT without stopping the code

    > I found a possible solution observing that in a child process generate
    > by a fork, the signal SIGABRT can be managed by a handler function
    > where you can do something.


    Why is this not possible in the parent? Ahaa, because the library code
    restores the default behaviour right after the handler returns, and
    kills the process again... bah.

    > In the program the child process ends (on the screen does not appear
    > ABORTED) then there is the execution of the father process etc.
    > This is a "dirty" solution because it is not possible, after the
    > overflow, to set any variable or flag for the father. I was
    > erroneously thinking to set a global variable in the handler function
    > so that the father, testing this variable, can understand the
    > overflow. This is wrong because when the child process disappear, also
    > the variable setting disappear so, for the father, nothing has
    > occurred.


    Right, but you can use shared memory. See manpages for shm_open, shmget,
    and mmap, which provide different mechanisms for this.

    > The only thing that can survive to the child process is a file.
    > For this reason in the handler function I write a empty file
    > overflow.dat and the father verify the existence of this file to
    > understand if overflow occurred.


    That's really not very pretty. It's probably better to do what Nate
    said: use setjmp to set a point in the code before you call into the
    part that might abort, and have the SIGABRT handler quit back out to
    that point with longjmp.


    Bjarni
    --

    INFORMATION WANTS TO BE FREE

  6. Re: How to handle SIGABRT without stopping the code

    Bjarni Juliusson writes:

    >> I found a possible solution observing that in a child process generate
    >> by a fork, the signal SIGABRT can be managed by a handler function
    >> where you can do something.

    >
    > Why is this not possible in the parent? Ahaa, because the library code
    > restores the default behaviour right after the handler returns, and
    > kills the process again... bah.


    Right. The libgcc arithmetic function calls abort() when an overflow
    occurs, and abort() is absolutely forbidden to return. (My system's
    libc implements this by unblocking SIGABRT and then raising it; then
    setting it to SIG_DFL and raising it again, and finally calling exit()
    (which really should be _exit(), I think, though I don't think it can
    ever be reached).) Moreover, the code and/or the compiler might rely on
    this behavior, so even if you could get abort() to return, it wouldn't
    necessarily have the effect of continuing your program with the right
    value of the addition.

  7. Re: How to handle SIGABRT without stopping the code

    On Nov 2, 10:05 pm, Bjarni Juliusson wrote:
    > > I found a possible solution observing that in a child process generate
    > > by a fork, the signal SIGABRT can be managed by a handler function
    > > where you can do something.

    >
    > Why is this not possible in the parent? Ahaa, because the library code
    > restores the default behaviour right after the handler returns, and
    > kills the process again... bah.
    >
    > > In the program the child process ends (on the screen does not appear
    > > ABORTED) then there is the execution of the father process etc.
    > > This is a "dirty" solution because it is not possible, after the
    > > overflow, to set any variable or flag for the father. I was
    > > erroneously thinking to set a global variable in the handler function
    > > so that the father, testing this variable, can understand the
    > > overflow. This is wrong because when the child process disappear, also
    > > the variable setting disappear so, for the father, nothing has
    > > occurred.

    >
    > Right, but you can use shared memory. See manpages for shm_open, shmget,
    > and mmap, which provide different mechanisms for this.
    >
    > > The only thing that can survive to the child process is a file.
    > > For this reason in the handler function I write a empty file
    > > overflow.dat and the father verify the existence of this file to
    > > understand if overflow occurred.

    >
    > That's really not very pretty. It's probably better to do what Nate
    > said: use setjmp to set a point in the code before you call into the
    > part that might abort, and have the SIGABRT handler quit back out to
    > that point with longjmp.
    >
    > Bjarni
    > --
    >
    > INFORMATION WANTS TO BE FREE


    I tried to use setjmp/longjmp but I have to face to common bug of
    these functions:
    http://www.cs.utk.edu/~plank/plank/c...p/lecture.html

    In fact, I tired to use setjmp in a function before a point where
    overflow might occur but I have to use longjmp in the
    SIGABRT handler (another function).
    It looks like (if I well understand) that is impossible return from a
    function that call setjmp.
    This means that setjmp have to be used only in the main.

    I do not like this because I want to produce a subroutine without put
    code in the main.


  8. Re: How to handle SIGABRT without stopping the code

    arkkimede@gmail.com writes:

    > I tried to use setjmp/longjmp but I have to face to common bug of
    > these functions:
    > http://www.cs.utk.edu/~plank/plank/c...p/lecture.html
    >
    > In fact, I tired to use setjmp in a function before a point where
    > overflow might occur but I have to use longjmp in the
    > SIGABRT handler (another function).
    > It looks like (if I well understand) that is impossible return from a
    > function that call setjmp.
    > This means that setjmp have to be used only in the main.
    >
    > I do not like this because I want to produce a subroutine without put
    > code in the main.


    [Recap: You want to detect integer overflow in your program, using a
    compiler option that calls abort() when an overflow occurs.]

    The link says "This is a very common bug with setjmp() and longjmp() --
    to use them properly, you CANNOT RETURN FROM THE PROCEDURE THAT CALLS
    setjmp()."

    That's an overstatement. More correctly, you cannot call longjmp()
    after the function that made the corresponding call to setjmp() has
    returned. So you have to ensure before returning that longjmp() won't
    be called again with that jmp_buf. So if you want this overflow
    handling only in one piece of your program, you can do something like

    jmp_buf jb;

    void handler(int sig) {
    longjmp(jb, 1);
    }

    void do_computations(void) {
    if (setjmp(jb) == 1)
    printf("Oh no, an overflow happened! Starting over.");
    signal(SIGABRT, handler);
    compute();
    signal(SIGABRT, SIG_DFL);
    /* now handler() won't be called anymore, nor will longjmp(jb,1) */
    return;
    }

  9. Re: How to handle SIGABRT without stopping the code

    On Nov 3, 7:56 pm, Nate Eldredge wrote:
    > arkkim...@gmail.com writes:
    > > I tried to use setjmp/longjmp but I have to face to common bug of
    > > these functions:
    > >http://www.cs.utk.edu/~plank/plank/c...tes/Setjmp/lec...

    >
    > > In fact, I tired to use setjmp in a function before a point where
    > > overflow might occur but I have to use longjmp in the
    > > SIGABRT handler (another function).
    > > It looks like (if I well understand) that is impossible return from a
    > > function that call setjmp.
    > > This means that setjmp have to be used only in the main.

    >
    > > I do not like this because I want to produce a subroutine without put
    > > code in the main.

    >
    > [Recap: You want to detect integer overflow in your program, using a
    > compiler option that calls abort() when an overflow occurs.]
    >
    > The link says "This is a very common bug with setjmp() and longjmp() --
    > to use them properly, you CANNOT RETURN FROM THE PROCEDURE THAT CALLS
    > setjmp()."
    >
    > That's an overstatement. More correctly, you cannot call longjmp()
    > after the function that made the corresponding call to setjmp() has
    > returned. So you have to ensure before returning that longjmp() won't
    > be called again with that jmp_buf. So if you want this overflow
    > handling only in one piece of your program, you can do something like
    >
    > jmp_buf jb;
    >
    > void handler(int sig) {
    > longjmp(jb, 1);
    >
    > }
    >
    > void do_computations(void) {
    > if (setjmp(jb) == 1)
    > printf("Oh no, an overflow happened! Starting over.");
    > signal(SIGABRT, handler);
    > compute();
    > signal(SIGABRT, SIG_DFL);
    > /* now handler() won't be called anymore, nor will longjmp(jb,1) */
    > return;
    >
    > }


    TANK YOU VERY MUCH!
    Now I'm able to manage the SIGABRT.
    (Probably also yesterday the code was correct but the global
    declaration of jb was destroyed by a local one (...grrrr...) and that
    was the really source of the problem.

    In the spirit of newsgroup and for future memory, probably in your
    code there's an else instruction missing to avoid, in the case of
    overflow, an infinite loop.

    jmp_buf jb;

    void handler(int sig) {
    longjmp(jb, 1);

    }

    void do_computations(void)
    {
    if (setjmp(jb) == 1)
    {
    printf("Oh no, an overflow happened! Starting over.");
    }
    else <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    {
    signal(SIGABRT, handler);
    compute();
    }
    signal(SIGABRT, SIG_DFL);
    /* now handler() won't be called anymore, nor will longjmp(jb,1) */
    return;
    }


    Ciao
    Daniele

  10. Re: How to handle SIGABRT without stopping the code

    arkkimede@gmail.com writes:

    > In the spirit of newsgroup and for future memory, probably in your
    > code there's an else instruction missing to avoid, in the case of
    > overflow, an infinite loop.
    >
    > jmp_buf jb;
    >
    > void handler(int sig) {
    > longjmp(jb, 1);
    >
    > }
    >
    > void do_computations(void)
    > {
    > if (setjmp(jb) == 1)
    > {
    > printf("Oh no, an overflow happened! Starting over.");
    > }
    > else <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    > {
    > signal(SIGABRT, handler);
    > compute();
    > }
    > signal(SIGABRT, SIG_DFL);
    > /* now handler() won't be called anymore, nor will longjmp(jb,1) */
    > return;
    > }


    Sure, if you like. I had in mind a situation where compute() gets its
    input from some external source (e.g. prompting the user), so when you
    call it again it uses different data that might not provoke an overflow.
    But of course you should do whatever's appropriate to your situation.

+ Reply to Thread