Ravi
Ravi

Reputation: 1710

Stackoverflow in setcontext()

Below is code I seen on Wikipedia. Does this results in stack overflow?

#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>

int main(int argc, const char *argv[]){
    ucontext_t context;

    getcontext(&context);
    puts("Hello world");
    sleep(1);
    setcontext(&context);
    return 0;
}

Why: When code reaches to setcontext(), it push new frame on stack. As setcontext() does not return, it's pushed frame will remain on stack. And as program is in infinite loop, it goes on pushing new frames on stack leading to stack overflow.

Upvotes: 0

Views: 539

Answers (2)

Klas Lindb&#228;ck
Klas Lindb&#228;ck

Reputation: 33273

setcontext will return the stack to the state it was at getcontext.

When you call setcontext, a new stack frame is pushed to the stack. setcontext will then revert the stack to the way it looked at getcontext, effectively removing the frame.

So the program does indeed create an infinite loop, but it will not result in stack overflow.

Upvotes: 1

dragosht
dragosht

Reputation: 3275

gdb says otherwise:

(gdb) list
1   #include <stdio.h>
2   #include <ucontext.h>
3   #include <unistd.h>
4   
5   int main(int argc, const char *argv[]){
6       ucontext_t context;
7   
8       getcontext(&context);
9       puts("Hello world");
10      //sleep(1);
(gdb) break 9
Breakpoint 1 at 0x4005bb: file test.c, line 9.
(gdb) run
Starting program: /home/dtarcatu/workspace/ctest/test 

Breakpoint 1, main (argc=1, argv=0x7fffffffe008) at test.c:9
9       puts("Hello world");
(gdb) print $rbp
$1 = (void *) 0x7fffffffdf20
(gdb) print $rsp
$2 = (void *) 0x7fffffffdb60
(gdb) c
Continuing.
Hello world

Breakpoint 1, main (argc=1, argv=0x7fffffffe008) at test.c:9
9       puts("Hello world");
(gdb) print $rbp
$3 = (void *) 0x7fffffffdf20
(gdb) print $rsp
$4 = (void *) 0x7fffffffdb60
(gdb) c
Continuing.
Hello world

Breakpoint 1, main (argc=1, argv=0x7fffffffe008) at test.c:9
9       puts("Hello world");
(gdb) print $rbp
$5 = (void *) 0x7fffffffdf20
(gdb) print $rsp
$6 = (void *) 0x7fffffffdb60

I'm not familiar with these context handling functions but it seems setcontext does not push new frames to the stack but rather restores the stack exactly the way it was. So you'll just end up in an infinite loop - no stack overflow ...

Upvotes: 2

Related Questions