Tôi đã giảm một mã bộ lập lịch sợi lớn đang tạo ra vấn đề cho các dòng bên dưới.
Điều tôi mong đợi là sự trở lại sạch sẽ trong bối cảnh, được truyền cho người xử lý, mọi lúc.
Điều tôi nhận được là "Trình xử lý" được in ra ba lần và sau đó là Lỗi phân đoạn.Sử dụng tham số thứ ba (void * context) của một trình xử lý sigaction với kết quả SIG_INFO trong một lỗi phân đoạn
#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;
}
Được sử dụng cả hai gcc-4.4.3 và gcc-4.4.5 trên hai bản phân phối Linux khác nhau.
Không chắc chắn 100% về điều này, nhưng bạn có thực sự cần sao chép 'ucontext_t' như thế không? Thay vào đó, chỉ cần làm 'setcontext ((ucontext_t *) context);' trong handler của bạn (đúc 'void *' sang đúng loại và truyền nó lên ...). – twalberg
Luôn luôn an toàn hơn khi lấy dữ liệu mà con trỏ trỏ tới (khi đối tượng gốc không cần thiết hoặc lớn), đặc biệt trong trường hợp bạn có thể mất nó. Ngoài ra, do thiếu ý tưởng và vài giờ thay đổi, tôi đã thử mọi biến thể của giải pháp đó (và thậm chí đã thử lại nó ngay bây giờ chỉ để chắc chắn) - không đi. –
Nói chung, tôi đồng ý về an toàn, nhưng tôi đã lưu ý trang người dùng cho 'setcontext()' tuyên bố 'ucontext_t' * phải * là một từ xuất phát từ' getcontext() ',' makecontext() ', hoặc là thông số được truyền đến một trình xử lý tín hiệu, mà bản sao chép thủ công bỏ qua. Không chắc làm thế nào làm một bản sao byte-khôn ngoan của cấu trúc có thể làm mất hiệu lực đó, nhưng figured nó không làm tổn thương để yêu cầu ... – twalberg