以下是我在Wikipedia上看到的代码。这会导致堆栈溢出吗?
#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;
}
原因:当代码到达setcontext()
时,它会在堆栈上推送新帧。由于setcontext()
没有返回,它的推帧将保持堆叠状态。并且由于程序处于无限循环中,它继续在堆栈上推送新帧,导致堆栈溢出。
答案 0 :(得分:2)
gdb否则说:
(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
我不熟悉这些上下文处理函数,但似乎setcontext
不会将新帧推送到堆栈,而是完全按照它的方式恢复堆栈。所以你最终会陷入无限循环 - 没有堆栈溢出......
答案 1 :(得分:1)
setcontext
会将堆栈返回到getcontext
处的状态。
当您调用setcontext
时,新的堆栈帧将被推送到堆栈。然后,setcontext
会将堆栈恢复为getcontext
的查看方式,从而有效地移除框架。
因此程序确实创建了一个无限循环,但它不会导致堆栈溢出。