Ho ridotto un enorme codice di schedulatore di fibra che stava producendo il problema nelle righe sottostanti.
Quello che mi aspetto è un ritorno pulito al contesto, passato al gestore, ogni volta.
Quello che ottengo è "Handler." Stampato tre volte e poi un errore di segmentazione.L'utilizzo del terzo parametro (contesto void * di un gestore di sigaction con SIG_INFO ha come risultato un errore di segmentazione
#include <ucontext.h>
#include <signal.h>
#include <stdio.h>
ucontext_t currently_executed_context;
void handler_sigusr1(int signum, siginfo_t* siginfo, void* context)
{
currently_executed_context = (*(ucontext_t*)context);
printf("Handler. ");
setcontext(¤tly_executed_context);
}
int main()
{
setbuf(stdout,0);
struct sigaction action_handler;
action_handler.sa_sigaction = handler_sigusr1;
action_handler.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1,&action_handler,NULL);
for(;;) { kill(getpid(),SIGUSR1); sleep(1); }
return 0;
}
Utilizzato sia gcc-4.4.3 che gcc-4.4.5 su due diverse distribuzioni Linux.
Non sicuro al 100% su questo, ma hai davvero bisogno di copiare il 'ucontext_t' in questo modo? Invece, fai semplicemente 'setcontext ((ucontext_t *) context);' nel tuo gestore (lanciare il 'void *' al tipo giusto e passarlo su ...). – twalberg
È sempre più sicuro prendere i dati a cui punta un puntatore (quando l'oggetto originale non è necessario o enorme), specialmente in una situazione in cui potresti perderlo. Inoltre, a causa della mancanza di idee e di diverse ore di modifiche, ho già provato tutte le varianti di quella soluzione (e l'ho persino ripensato ora per sicurezza) - no go. –
In generale, sono d'accordo sulla sicurezza, ma ho notato che la pagina man di 'setcontext()' afferma che 'ucontext_t' * deve * essere uno che proviene da' getcontext() ',' makecontext() ', o come parametro passato a un gestore di segnali, che la copia manuale sorta ignora. Non sono sicuro di come fare una copia in byte della struttura potrebbe invalidarlo, ma ho pensato che non faceva male a chiedere ... – twalberg