2010-03-22 33 views
7

Tôi đang cố gắng theo dõi một vụ tai nạn rất kỳ quặc. Điều kỳ lạ về nó là một cách giải quyết mà ai đó đã khám phá và điều tôi không thể giải thích được.cách exec có thể thay đổi hành vi của chương trình exec'ed

Cách giải quyết là chương trình nhỏ này mà tôi sẽ đề cập đến là 'Á hậu':

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <errno.h> 

int main(int argc, char *argv[]) 
{ 
    if (argc == 1) 
    { 
     fprintf(stderr, "Usage: %s prog [args ...]\n", argv[0]); 
     return 1; 
    } 

    execvp(argv[1], argv + 1); 

    fprintf(stderr, "execv failed: %s\n", strerror(errno)); 

    // If exec returns because the program is not found or we 
    // don't have the appropriate permission 
    return 255; 
} 

Như bạn có thể thấy, tất cả chương trình này thực hiện là sử dụng execvp để thay thế bản thân với một chương trình khác nhau.

Các chương trình bị treo khi nó được gọi trực tiếp từ dòng lệnh:

/path/to/prog args # this crashes 

nhưng hoạt động tốt khi nó gián tiếp được gọi qua Á hậu shim tôi:

/path/to/runner /path/to/prog args # works successfully 

Đối với cuộc sống của tôi, Tôi có thể tìm ra cách có thêm một exec có thể thay đổi hành vi của chương trình đang chạy (vì bạn có thể thấy chương trình không thay đổi môi trường).

Một số nền về sự cố. Bản thân sự cố xảy ra trong thời gian chạy C++. Cụ thể, khi chương trình thực hiện throw, phiên bản lỗi không chính xác cho rằng không có kết quả nào phù hợp (mặc dù có) và gọi số terminate. Khi tôi gọi chương trình qua Á hậu, ngoại lệ được bắt đúng cách.

Câu hỏi của tôi là bất kỳ ý tưởng nào tại sao exec bổ sung thay đổi hành vi của chương trình exec'ed?

+0

Tôi không biết: Nhưng execvp có thay đổi thư mục làm việc không? Bạn đang đi qua đối số nào? –

+0

@MartinYork - AFAIK, 'execvp' không bao giờ thay đổi thư mục làm việc (yêu cầu cuộc gọi đến' chdir' và runner không làm điều đó). Các đối số cụ thể không liên quan; hành vi được mô tả là độc lập với các đối số cụ thể được truyền cho chương trình. –

+1

Nó có làm điều tương tự nếu bạn sử dụng 'execv()' thay vì 'execvp()'? – caf

Trả lời

3

Có thể các tệp .so do người tải tải đang khiến người chạy phải hoạt động chính xác. Hãy thử ldd'ing mỗi của các tập tin nhị phân và xem nếu bất kỳ thư viện đang tải phiên bản khác nhau/địa điểm.

+1

Vấn đề là liệu 'ld-linux.so.2' ánh xạ một đối tượng chia sẻ cụ thể vào không gian địa chỉ trước nhị phân chính hay sau (lỗi thực tế ở đâu đó nhưng do hoàn cảnh, lỗi chỉ hiển thị khi SO được ánh xạ với địa chỉ thấp hơn thì nhị phân chính). –

0

Là ảnh chụp trong bóng tối: nhân đôi có thể thay đổi thứ tự các biến môi trường trong RAM.

Môi trường là cấu trúc bộ nhớ có con trỏ; kernel sao chép cấu trúc đó vào không gian địa chỉ của tiến trình mới. Thứ tự thực tế của các phần tử trong RAM có thể thay đổi trong bản sao đó (các biến môi trường không được đặt theo ngữ nghĩa, nhưng các địa chỉ trong RAM có thứ tự). Với hai exec(), thứ tự có thể được sửa đổi hai lần.

Việc thay đổi thứ tự chuỗi trong bộ nhớ RAM khai quật một lỗi có phần hơi kỳ quái, nhưng những điều kỳ lạ đã xảy ra.

+0

Cảm ơn bạn đã đề xuất nhưng điều đó dường như không phải như vậy. Tôi đã đổ khối môi trường thô và chúng có cùng thứ tự trong cả hai. –

0

Tôi tự hỏi nếu bạn đang truyền một cái gì đó khác nhau trong argv [0] cho vỏ là gì. Tôi không thể thấy rõ ràng từ những gì bạn đang viết ở trên, nhưng có thể bạn đang đặt argv [0] thành đối số đầu tiên thực tế cho chương trình, trong khi trình vỏ đặt nó thành tên gọi của nó (ví dụ: đường dẫn đầy đủ hoặc ngắn)

+0

@MarkR - cảm ơn đề xuất của bạn. Tôi sửa đổi runner để 'argv [0]' sẽ không bao gồm đường dẫn. Thật không may, tôi vẫn thấy hành vi tương tự. –

1

Có lẽ chương trình được gọi bị rò rỉ bộ nhớ. Hãy thử chạy nó với valgrind hoặc một số công cụ kiểm tra bộ nhớ khác. Sau khi bạn có một lỗi bộ nhớ mọi thứ khác là hành vi không xác định (và vì vậy tất cả mọi thứ có thể xảy ra).

+0

Khác sau đó bình thường vẫn có thể truy cập tại các khối thoát, Valgrind không phát hiện bất kỳ lỗi nào trên phiên bản kết thúc (hoặc phiên bản không kết thúc cho vấn đề đó). –

0

Tôi đoán hai điều bạn có thể so sánh giữa các phiên bản 'đang hoạt động' và 'gặp sự cố' - các bộ mô tả tệp mở và trình xử lý tín hiệu - vì những điều này được thực hiện bởi exec.

Tôi không thể thấy chúng là vấn đề/khác nhau, nhưng có thể đáng để loại bỏ chúng.

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