2013-02-27 11 views
6

Próbuję zrozumieć, czy polecenie getcontext/setcontext będzie działać poprawnie w określonym scenariuszu.przełączanie w górę/w dół stosu za pomocą getcontext/setcontext

Widzę, w jaki sposób można użyć polecenia setcontext(), aby cofnąć stos do określonego miejsca w historii.

#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 called\n"); 
     rollback++; 
     func(); 
    } 
    else 
    { 
     printf("setcontext has been called\n"); 
    } 
} 

Ale zastanawiałem się, czy po odwijania można ponownie wiatr z powrotem do miejsca, które było w przyszłości? Przypuszczam, że to zależy od wywołania getcontext() rejestruje kopię stosu i nie mogę znaleźć dokładne szczegóły w dokumentacji.

#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 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); 
    } 
} 

Odpowiedz

4

getcontext nie kopiuje stos, to tylko zrzuca rejestry (w tym wskaźnik stosu) i niewiele danych kontekstowych, takich jak maski sygnału itd

Kiedy zeskoczyć stos unieważnia ona górną kontekst. Nawet jeśli nie wykonasz żadnych wywołań funkcji, pomyśl o obsłudze sygnału, który może tam wykonać. Jeśli chcesz przeskoczyć między dwoma stosami, musisz makecontext.

dodałem zmienną, która pokazuje, że kod jest nieprawidłowy:

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 
} 

Na moim komputerze skutkuje:

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

można zapewnić poprawną wersję kodu w swoim poście użyciem 'makecontext '? Dokładniej, chciałbym stworzyć funkcję wywołania z cienkiego powietrza w procedurze obsługi sygnału (która powinna zostać wykonana po powrocie tresera). Chciałbym również, aby stos rozwijania stosu (rzut/catch) działał poprawnie, jeśli wrzucę tę nowo utworzoną funkcję i spróbuję/złapię zewnętrzny oryginalny kontekst. Wymaga to utworzenia dynamicznego wywołania funkcji (tworzenie ramki stosu), które zakładam. Nie jestem pewien, czy jest to możliwe z setcontext, czy nie (uc_link w ucontext_t?). – Etherealone

+0

Udało mi się użyć makecontext na nowo utworzonym wywołaniu funkcji, ale ustawienie uc_link do ostatniego parametru signal_handler (ucontext_t) nie powraca poprawnie do starego kontekstu po wykonaniu nowego wywołania funkcji. (P.S. Celem rozwijania stosu w moim poprzednim komentarzu jest to, że chcę wyczyścić niepoprawną operację, która tworzy sygnał, który nie jest katastrofalny). – Etherealone

+0

@Etherealone, myślę, że jest to zbyt skomplikowane dla tego wątku komentarza, ale nie krępuj się połączyć mnie z pytaniem, jeśli je utworzysz. – zch

Powiązane problemy