2013-02-27 17 views
6

Tôi đang cố gắng hiểu nếu getcontext/setcontext sẽ hoạt động chính xác trong một tình huống cụ thể.chuyển đổi lên/xuống ngăn xếp với getcontext/setcontext

Tôi có thể xem cách setcontext() có thể được sử dụng để thư giãn ngăn xếp trở lại một địa điểm nhất định trong lịch sử.

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

Nhưng tôi đã tự hỏi nếu sau khi thư giãn, bạn có thể quay trở lại một địa điểm trong tương lai? Tôi cho rằng điều này phụ thuộc vào cuộc gọi getcontext() chụp một bản sao của ngăn xếp và tôi không thể tìm thấy chi tiết chính xác trong tài liệu.

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

Trả lời

4

getcontext không sao chép chồng, nó chỉ bãi đăng ký (bao gồm con trỏ ngăn xếp) và dữ liệu bối cảnh hơi giống như mặt nạ tín hiệu vv

Khi bạn nhảy xuống ngăn xếp nó làm mất hiệu lực bối cảnh hàng đầu. Ngay cả khi bạn sẽ không thực hiện bất kỳ cuộc gọi hàm nào, hãy nghĩ về trình xử lý tín hiệu có thể thực hiện ở đó. Nếu bạn muốn chuyển đổi giữa hai ngăn xếp, bạn cần phải makecontext.

tôi thêm biến đó chứng tỏ rằng mã của bạn không hợp lệ:

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 
} 

Trên máy tính của tôi nó kết quả trong:

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

bạn có thể cung cấp các phiên bản đúng của mã trong bài viết của bạn sử dụng 'makecontext '? Để được chính xác, tôi muốn tạo ra một cuộc gọi chức năng ra khỏi không khí mỏng trong một bộ xử lý tín hiệu (mà nên được thực hiện sau khi trả về xử lý). Tôi cũng muốn ngăn xếp thư giãn (ném/bắt) để hoạt động chính xác nếu tôi ném vào hàm mới được tạo này và thử/nắm bắt trên bối cảnh ban đầu bên ngoài. Điều này đòi hỏi phải tạo ra một cuộc gọi chức năng động (tạo khung ngăn xếp) tôi giả sử. Tôi không chắc chắn nếu nó có thể với setcontext hay không (uc_link trong ucontext_t?). – Etherealone

+0

Tôi đã quản lý để sử dụng makecontext trên cuộc gọi hàm mới được tạo này nhưng thiết lập uc_link thành tham số cuối cùng của signal_handler (ucontext_t) không trả lại chính xác ngữ cảnh cũ sau khi thực hiện cuộc gọi hàm mới. (P.S. Mục đích của việc mở thư giãn trong bình luận trước của tôi là tôi muốn xóa sạch một hoạt động vi phạm tạo ra một tín hiệu không phải là thảm họa). – Etherealone

+0

@Etherealone, tôi nghĩ rằng đó là quá phức tạp cho chủ đề bình luận này, nhưng cảm thấy tự do để liên kết tôi đến một câu hỏi, bạn nên tạo ra một. – zch

Các vấn đề liên quan