setjmp and longjmp problem

Discussion in 'C Programming' started by aleksa, Sep 5, 2010.

  1. aleksa

    aleksa Guest

    static jmp_buf environment;

    void testproc (void)
    {
    longjmp(environment, 1);
    }

    long do_setjmp (void)
    {
    return setjmp(environment);
    }

    long testing (void)
    {
    long status;

    status = setjmp(environment);
    // status = do_setjmp();

    if (status == 0) {
    testproc();
    return -1;
    }

    return status;
    }

    Prog starts in 'testing', calls setjmp then calls testproc which calls
    longjmp.

    Now, if I call setjmp from 'testing', it works. First time, returned
    status is zero,
    so testproc gets called, second time is 1, so I return the status(1).

    But, if I call setjmp with do_setjmp, when I call testproc and it
    calls longjmp,
    longjmp does return where it is supposed to (in do_setjmp) but
    do_setjmp
    then returns to 'return -1;', i.e. after a call to testproc, and not
    to 'if (status == 0)'.

    Why?

    Cheers,
    Aleksandar
     
    aleksa, Sep 5, 2010
    #1
    1. Advertising

  2. In article <>,
    aleksa <> wrote:

    > static jmp_buf environment;
    >
    > void testproc (void)
    > {
    > longjmp(environment, 1);
    > }
    >
    > long do_setjmp (void)
    > {
    > return setjmp(environment);


    You cannot longjmp to a target after its containing function is exitted. In this
    case, as a do_setjmp returns, the target environment is invalid. (Or the call
    frame of the setjmp has to still be on the stack when the longjmp is called.)

    > long testing (void)
    > {
    > long status;
    >
    > status = setjmp(environment);


    This setjmp remains valid until testing is exitted.

    > // status = do_setjmp();
    >
    > if (status == 0) {
    > testproc();


    The longjmp can be in a function called from setjmp's containing function. The
    function testing is still active when testproc is called, so the target
    enviroment is still valid and execution should resume above with status==1.

    > return -1;
    > }
    >
    > return status;
    > }
    >
    > Prog starts in 'testing', calls setjmp then calls testproc which calls
    > longjmp.
    >
    > Now, if I call setjmp from 'testing', it works. First time, returned
    > status is zero,
    > so testproc gets called, second time is 1, so I return the status(1).


    --
    Damn the living - It's a lovely life. I'm whoever you want me to be.
    Silver silverware - Where is the love? At least I can stay in character.
    Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
    Damn the living - It's a lovely life.
     
    Chine Bleu, Blanc, et Rouge, Sep 5, 2010
    #2
    1. Advertising

  3. On 05/09/2010 21:39, aleksa wrote :
    > static jmp_buf environment;
    >
    > void testproc (void)
    > {
    > longjmp(environment, 1);
    > }
    >
    > long do_setjmp (void)
    > {
    > return setjmp(environment);
    > }
    >
    > long testing (void)
    > {
    > long status;
    >
    > status = setjmp(environment);
    > // status = do_setjmp();
    >
    > if (status == 0) {
    > testproc();
    > return -1;
    > }
    >
    > return status;
    > }
    >
    > Prog starts in 'testing', calls setjmp then calls testproc which calls
    > longjmp.
    >
    > Now, if I call setjmp from 'testing', it works. First time, returned
    > status is zero,
    > so testproc gets called, second time is 1, so I return the status(1).
    >
    > But, if I call setjmp with do_setjmp, when I call testproc and it
    > calls longjmp,
    > longjmp does return where it is supposed to (in do_setjmp) but
    > do_setjmp
    > then returns to 'return -1;', i.e. after a call to testproc, and not
    > to 'if (status == 0)'.
    >
    > Why?


    Because the function do_setjmp() that did the setjmp has terminated
    execution when testproc does longjmp(), and that's prohibited by
    7.13.2.1#2:
    The longjmp function restores the environment saved by the most
    recent invocation of the setjmp macro in the same invocation of
    the program with the corresponding jmp_buf argument. If (..)
    the function containing the invocation of the setjmp macro has
    terminated execution (for example, by executing a return statement
    (..)) in the interim (..) the behavior is undefined.

    Francois Grieu
     
    Francois Grieu, Sep 5, 2010
    #3
  4. aleksa

    aleksa Guest

    OK, I understand, thank you both.
     
    aleksa, Sep 5, 2010
    #4
  5. aleksa <> writes:
    [...]
    > long do_setjmp (void)
    > {
    > return setjmp(environment);
    > }

    [...]

    setjmp() returns int. Why are you storing the result in a long?
    (Not that that has anything to do with the problems you're seeing.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 5, 2010
    #5
  6. On 06/09/2010 20:13, Nobody wrote:
    > On Sun, 05 Sep 2010 22:10:19 +0200, Francois Grieu wrote:
    >
    >>> Why?

    >>
    >> Because the function do_setjmp() that did the setjmp has terminated
    >> execution when testproc does longjmp(), and that's prohibited by
    >> 7.13.2.1#2:

    >
    > Ah, but it triggers UB long before that. 7.13.1.1#4 and #5:
    >
    > [#4] An invocation of the setjmp macro shall appear only in
    > one of the following contexts:
    >
    > -- the entire controlling expression of a selection or
    > iteration statement;
    >
    > -- one operand of a relational or equality operator with
    > the other operand an integer constant expression, with
    > the resulting expression being the entire controlling
    > expression of a selection or iteration statement;
    >
    > -- the operand of a unary ! operator with the resulting
    > expression being the entire controlling expression of a
    > selection or iteration statement; or
    >
    > -- the entire expression of an expression statement
    > (possibly cast to void).
    >
    > [#5] If the invocation appears in any other context, the
    > behavior is undefined.
    >


    Right. The working variant of OP's code also infringes on that with
    status = do_setjmp();

    This is UB, although many if not most implementations are happy with it.

    Francois Grieu
     
    Francois Grieu, Sep 7, 2010
    #6
    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. Thomas Baruchel

    How dirty is setjmp+fopen+longjmp ?

    Thomas Baruchel, Oct 2, 2003, in forum: C Programming
    Replies:
    2
    Views:
    466
    Eric Sosman
    Oct 2, 2003
  2. Zheng Da
    Replies:
    8
    Views:
    506
    Christian Bau
    Nov 7, 2005
  3. Replies:
    3
    Views:
    419
    Fred Kleinschmidt
    Feb 23, 2007
  4. jacob navia

    The stack and longjmp/setjmp

    jacob navia, Mar 4, 2008, in forum: C Programming
    Replies:
    34
    Views:
    1,467
    David Thompson
    Mar 31, 2008
  5. harman

    Problem with setjmp/longjmp

    harman, Mar 16, 2010, in forum: C Programming
    Replies:
    0
    Views:
    342
    harman
    Mar 16, 2010
Loading...

Share This Page