我想了解getcontext/setcontext是否会在特定场景中正确工作。
我可以看到如何使用setcontext()将堆栈展开到历史上的某个位置。
#include <stdio.h>
#include <ucontext.h>
int rollback = 0;
ucontext_t context;
void func(void)
{
setcontext(cp);
}
int main(void)
{
getcontext(&context);
if (rollback == 0)
{
printf("getcontext has been calledn");
rollback++;
func();
}
else
{
printf("setcontext has been calledn");
}
}
但是我想知道在放松之后你是否可以回到未来的一个地方?我想这取决于getcontext()
调用捕获堆栈的副本,我无法在文档中找到确切的细节。
#include <stdio.h>
#include <ucontext.h>
int rollback = 0;
int backToFuture = 0;
ucontext_t context;
ucontext_t futureContext;
void func(void)
{
// Some complex calc
if (some-condition)
{
getcontext(&futureContext); // After returning I want to come back
// here to carry on with my work.
if (backToFuture == 0)
{
setcontext(&context); // rewind to get stuff-done
}
}
// Finishe work
}
int main(void)
{
getcontext(&context);
if (rollback == 0)
{
printf("getcontext has been calledn");
rollback++;
func();
// eventually always return here.
}
else
{
printf("setcontext has been calledn");
// Do specialized work that needed to be done
// May involve function calls.
//
// I worry that anything the adds new stack frames
// will disrupt the saved state of futureContext
//
// But without detailed information I can not be sure
// if this is an allowed senario.
backToFuture = 1;
setcontext(&futureContext);
}
}
getcontext
不复制堆栈,它只转储寄存器(包括堆栈指针)和一些上下文数据,如信号掩码等
当你向下跳转堆栈时,它使顶部上下文无效。即使你不做任何函数调用,也要考虑可以在那里执行的信号处理程序。如果你想在两个堆栈之间跳转,你需要makecontext
。
我添加了一个变量来证明你的代码是无效的:
void func(void)
{
// Some complex calc
if (1)
{
volatile int neverChange = 1;
getcontext(&futureContext); // After returning I want to come back
// here to carry on with my work.
printf("neverchange = %dn", neverChange);
if (backToFuture == 0)
{
setcontext(&context); // rewind to get stuff-done
}
}
// Finishe work
}
在我的机器上,结果是:
getcontext has been called
neverchange = 1
setcontext has been called
neverchange = 32767