2013-02-27 13 views
6

Sto cercando di capire se getcontext/setcontext funzionerà correttamente in uno scenario specifico.commutazione su/giù stack con getcontext/setcontext

Posso vedere come setcontext() può essere utilizzato per riposizionare lo stack in un determinato punto della cronologia.

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

Ma mi stavo chiedendo se dopo un po 'di riposo si può tornare indietro in un posto che era nel futuro? Suppongo che ciò dipenda dalla chiamata getcontext() che acquisisce una copia dello stack e non riesco a trovare i dettagli esatti nella documentazione.

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

risposta

4

getcontext non copia dello stack, è dump solo registri (tra cui stack pointer) e un po 'di dati di contesto come maschera del segnale, ecc

Quando saltate giù la pila annulla contesto superiore. Anche se non farai nessuna funzione, le chiamate pensano al gestore del segnale che può eseguire lì. Se si desidera saltare tra due pile è necessario makecontext.

ho aggiunto variabile che dimostra che il codice non è valido:

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 
} 

Sulla mia macchina si traduce in:

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

Potete fornire la versione corretta del codice nel tuo post utilizzando 'makecontext '? Per essere precisi, vorrei creare una chiamata di funzione dal nulla in un gestore di segnale (che dovrebbe essere eseguita dopo il ritorno del gestore). Mi piacerebbe anche che lo stack si srotoli (throw/catch) per funzionare correttamente se lancio questa funzione appena creata e cerco/catturo il contesto originale esterno. Ciò presuppone la creazione di una chiamata di funzione dinamica (creazione di frame stack). Non sono sicuro che sia possibile con setcontext o no (uc_link in ucontext_t?). – Etherealone

+0

Sono riuscito a usare makecontext su questa chiamata di funzione appena creata ma impostare uc_link sull'ultimo parametro di signal_handler (ucontext_t) non ritorna correttamente al vecchio contesto dopo l'esecuzione della nuova chiamata di funzione. (P.S. Lo scopo della pila che si svolge nel mio precedente commento è che voglio annullare in modo pulito un'operazione offensiva che crea un segnale che non è catastrofico). – Etherealone

+0

@Etherealone, penso che sia troppo complicato per questo thread di commenti, ma sentiti libero di collegarmi ad una domanda, dovresti crearne una. – zch

Problemi correlati