getcontext/setcontext - Unix

This is a discussion on getcontext/setcontext - Unix ; I can't figure out why, but these functions don't work the way I expect. What happens is that it gets the context fine in the call_cc function and then it sets the context in the apply function just fine - ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: getcontext/setcontext

  1. getcontext/setcontext

    I can't figure out why, but these functions don't work the way I
    expect. What happens is that it gets the context fine in the call_cc
    function and then it sets the context in the apply function just fine
    - I know this because of the second "getcontext returned..." message.
    But then instead of returning from call_cc just before the "main:
    i=..." message, call_cc returnes at the point that apply was called -
    and the "error! i=..." message is printed and the program ends. Why
    is it doing something I don't expect?

    Thanks,

    Jerry

    Compiler:

    VisualAge C++ Professional / C for AIX Compiler, Version 6

    Program:

    #include
    #include
    ucontext_t context = {0};
    void call_cc(int i) {
    printf("call_cc: i=%d\n",i);
    int x = getcontext(&context);
    printf("getcontext returned %d\n",x);
    }
    void apply(int i) {
    printf("apply: i=%d\n",i);
    int x = setcontext(&context);
    printf("setcontext returned %d\n",x);
    }
    int main() {
    int i=0;
    call_cc(i);
    printf("main: i=%d\n",i);
    if(i==0) {
    i++;
    apply(i);
    printf("error! i=%d\n",i);
    }
    printf("done! i=%d\n",i);
    return 0;
    }

    Actual Output:

    call_cc: i=0
    getcontext returned 0
    main: i=0
    apply: i=1
    getcontext returned 0
    error! i=1
    done! i=1

    Expected Output:

    call_cc: i=0
    getcontext returned 0
    main: i=0
    apply: i=1
    getcontext returned 0
    main: i=1
    done! i=1


  2. Re: getcontext/setcontext

    jerry.jeremiah@gmail.com writes:

    > I can't figure out why, but these functions don't work the way I
    > expect.


    The context includes current stack pointer. As soon as you return
    from call_cc(), the context that you stored becomes invalid -- it
    refers to stack locations that are "no longer there" -- have been
    popped off the stack. Calling setcontext() on such context invokes
    undefined behavior.

    You may use the context in the function that called getcontext(),
    or in any functions called from it; but never after the caller of
    getcontext() returns.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  3. Re: getcontext/setcontext

    jerry.jeremiah@gmail.com writes:
    >I can't figure out why, but these functions don't work the way I
    >expect. What happens is that it gets the context fine in the call_cc
    >function and then it sets the context in the apply function just fine
    >- I know this because of the second "getcontext returned..." message.
    >But then instead of returning from call_cc just before the "main:
    >i=..." message, call_cc returnes at the point that apply was called -
    >and the "error! i=..." message is printed and the program ends. Why
    >is it doing something I don't expect?


    The compiler is keeping 'i' in a register. When you return from
    the getcontext the second time, it returns the value of 'i' to the
    original saved value.

    scott


  4. Re: getcontext/setcontext

    On Oct 26, 6:10 pm, Paul Pluzhnikov
    wrote:
    > jerry.jerem...@gmail.com writes:
    > > I can't figure out why, but these functions don't work the way I
    > > expect.

    >
    > The context includes current stack pointer. As soon as you return
    > from call_cc(), the context that you stored becomes invalid -- it
    > refers to stack locations that are "no longer there" -- have been
    > popped off the stack. Calling setcontext() on such context invokes
    > undefined behavior.
    >
    > You may use the context in the function that called getcontext(),
    > or in any functions called from it; but never after the caller of
    > getcontext() returns.
    >
    > Cheers,


    I thought getcontext stored the entire stack so that all stack
    variables were saved. I figured this meant the stack (including the
    correct return address of call_cc would be restored. If it only
    stores the stack pointer then it isn't much more useful than lngjmp...

    Jerry


  5. Re: getcontext/setcontext

    jerry.jeremiah@gmail.com writes:

    > I thought getcontext stored the entire stack so that all stack
    > variables were saved.


    The wording in the man page could probably use some improvement.
    It says

    The ucontext_t type that ucp points to defines the user context and
    includes the contents of the calling process' machine registers,
    the signal mask, and the current execution stack

    > I figured this meant the stack (including the
    > correct return address of call_cc would be restored.


    That would require storing a copy of the *entire* stack (possibly
    many MBytes). Where do you suppose storage for that copy comes from?

    In theory, getcontext could malloc() that memory, but then this
    sequence would leak it:

    getcontext(&ctx); getcontext(&ctx);

    > If it only
    > stores the stack pointer then it isn't much more useful than lngjmp...


    That's right, it isn't.

    Most of getcontext() utility comes from makecontext(), which provides
    for machine-independent way to write coroutines.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  6. Re: getcontext/setcontext

    Thanks for the help.

    I was trying to amke a "call with current continuation" function so I
    was hoping it made a copy of the entire stack.

    C'est la voie.

    Jerry

    On Oct 29, 5:30 pm, Paul Pluzhnikov
    wrote:
    > jerry.jerem...@gmail.com writes:
    > > I thought getcontext stored the entire stack so that all stack
    > > variables were saved.

    >
    > The wording in the man page could probably use some improvement.
    > It says
    >
    > The ucontext_t type that ucp points to defines the user context and
    > includes the contents of the calling process' machine registers,
    > the signal mask, and the current execution stack
    >
    > > I figured this meant the stack (including the
    > > correct return address of call_cc) would be restored.

    >
    > That would require storing a copy of the *entire* stack (possibly
    > many MBytes). Where do you suppose storage for that copy comes from?
    >
    > In theory, getcontext could malloc() that memory, but then this
    > sequence would leak it:
    >
    > getcontext(&ctx); getcontext(&ctx);
    >
    > > If it only
    > > stores the stack pointer then it isn't much more useful than lngjmp...

    >
    > That's right, it isn't.
    >
    > Most of getcontext() utility comes from makecontext(), which provides
    > for machine-independent way to write coroutines.
    >
    > Cheers,
    > --
    > In order to understand recursion you must first understand recursion.
    > Remove /-nsp/ for email.




+ Reply to Thread