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