basculer la stack avec getcontext / setcontext

J’essaie de comprendre si getcontext / setcontext fonctionnera correctement dans un scénario spécifique.

Je peux voir comment setcontext () peut être utilisé pour dérouler la stack à un certain endroit de l’histoire.

#include  #include  int rollback = 0; ucontext_t context; void func(void) { setcontext(cp); } int main(void) { getcontext(&context); if (rollback == 0) { printf("getcontext has been called\n"); rollback++; func(); } else { printf("setcontext has been called\n"); } } 

Mais je me demandais si après un moment de détente, vous pouviez revenir dans un endroit qui était dans le futur. Je suppose que cela dépend de l’appel de getcontext() capture une copie de la stack et je ne trouve pas les détails exacts dans la documentation.

 #include  #include  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 called\n"); rollback++; func(); // eventually always return here. } else { printf("setcontext has been called\n"); // 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 ne copie pas la stack, il ne getcontext que les registres (y compris le pointeur de stack) et un peu de données de contexte comme le masque de signal, etc.

    Lorsque vous sautez dans la stack, le contexte supérieur est invalidé. Même si vous ne faites aucun appel de fonction, pensez au gestionnaire de signal qui peut y être exécuté. Si vous voulez sauter entre deux stacks, vous devez makecontext .

    J’ai ajouté une variable qui démontre que votre code est invalide:

     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 = %d\n", neverChange); if (backToFuture == 0) { setcontext(&context); // rewind to get stuff-done } } // Finishe work } 

    Sur ma machine, il en résulte:

     getcontext has been called neverchange = 1 setcontext has been called neverchange = 32767