2011-02-02 53 views
6

Tôi đã quá tải cuộc gọi hệ thống fork() và tạo phiên bản của riêng mình fork() bằng RTLD_NEXT. Tức là, dlsym(RTLD_NEXT, fork). Điều này sẽ nhấn phiên bản của tôi của ngã ba. Sau này tôi muốn nhân rộng nhiệm vụ thực tế của cuộc gọi hệ thống fork(), đó là, tạo ra quá trình con và trả lại pid, và một số chức năng bổ sung hơn.Quá tải ngã ba()

Tôi không thể tìm ra cách thực hiện điều đó. Tôi đã kiểm tra mã nguồn hạt nhân cho fork() (fork.c) và không thể tìm ra nhiều.

Việc làm này:

dlsym(RTLD_NEXT,fork); 
int fork(void) { 
    int pid=_fork(); // Trying to call actual fork does not work 
    return pid; 
} 

Làm thế nào tôi có thể làm điều đó? Dưới đây là liên kết tới kernel mã nguồn cho ngã ba: http://lxr.linux.no/linux+v2.6.32/kernel/fork.c#L10

Chỉnh sửa (kéo từ bình luận):

tôi đang làm việc trên một sự rò rỉ công cụ phát hiện, và công cụ này phát hiện một đôi miễn phí khi một quá trình con xóa bộ nhớ được cấp bởi cha mẹ. Để khắc phục điều này, tôi sẽ ghi đè lên fork() và bất cứ khi nào có fork(), bảng phân bổ bộ nhớ của phụ huynh sẽ được nhân đôi với đứa trẻ.

+0

Bạn có ý nghĩa gì bởi "không hoạt động"? Lỗi thời gian chạy? Lỗi trình biên dịch? – Simone

+0

@Simone: _fork(); // Lỗi: _fork không được khai báo. Ý tưởng của tôi là để làm cho nó nhấn phiên bản hạt nhân thực tế của ngã ba và không phải của tôi. Hy vọng nó làm cho rõ ràng bây giờ. – kingsmasher1

+0

Chính xác, bạn muốn đạt được điều gì bằng cách thực hiện việc này? Mục tiêu cuối cùng của bạn là gì? – Omnifarious

Trả lời

3

Bạn sẽ có thể gọi số thực tế fork với syscall(SYS_fork) sau khi bao gồm <sys/syscall.h>. Xem syscall(2).

+0

Tôi không chắc chắn có thực sự một cuộc gọi hệ thống 'ngã ba 'nữa. Tôi nghĩ rằng nó đã được dịch sang một cuộc gọi 'clone' với một bộ tham số cụ thể. – Omnifarious

+0

@larsmans: Điều đó mang lại một số ý tưởng hay !! Tuyệt quá. Hãy để tôi thử nó ngay bây giờ và xem nó có hoạt động không. – kingsmasher1

+0

@Omnifarious: nó vẫn hoạt động. Ngược lại, tôi đoán vậy. –

7

Bạn sẽ không nhận được bất kỳ thứ gì hữu ích từ mã nguồn hạt nhân cho fork. Mã của bạn sẽ không được phép làm những điều mà hạt nhân thực hiện cho dù bạn đang quản lý thư viện nào. Đó là một ranh giới cứng mà không thể bị vi phạm mà không cần viết một mô-đun hạt nhân.

Tất cả mã thư viện cho fork sẽ thiết lập và thực hiện lệnh đặc biệt chuyển sang chế độ hạt nhân nơi mã fork của hạt nhân thực thi. Có một cách để đưa hướng dẫn đặc biệt này vào mã của riêng bạn. Đó là hàm syscall. Vì fork không có đối số, nên tương đối dễ sử dụng chức năng này để thực hiện cuộc gọi hệ thống.

Nhưng đây không phải là những gì tôi khuyên bạn nên làm. Tôi khuyên bạn làm điều này thay vì:

typedef int (*forkfunc_t)(void); 

int fork(void) 
{ 
    forkfunc_t sysfork = (forkfunc_t)dlsym(RTLD_DEFAULT, "fork"); 
    return sysfork(); 
} 

Về cơ bản, bất cứ điều gì chia sẻ hackery thư viện bạn làm thế, về cơ bản bạn nên tìm một số cách để lấy giá trị trước đó của fork chức năng trước khi bạn thay thế nó với riêng bạn.

+0

Tôi đang làm việc trên một công cụ phát hiện rò rỉ, và công cụ này phát hiện một đôi miễn phí khi một quá trình con xóa bộ nhớ được phân bổ bởi phụ huynh. Để khắc phục điều này tôi sẽ ghi đè lên ngã ba(), và bất cứ khi nào có một ngã ba(), bảng phân bổ bộ nhớ của cha mẹ sẽ được nhân đôi với đứa trẻ. – kingsmasher1

+0

@ kingsmasher1: Ahh, vì vậy bạn không cần phải sửa đổi hạt nhân đang làm gì với 'fork', bạn chỉ cần đảm bảo rằng bạn chặn nó và bọc nó một cách thích hợp. Điều đó rất có thể thực hiện được, và kỹ thuật thư viện được chia sẻ của bạn không quá tệ để tìm hiểu về nó. – Omnifarious

+0

@ kingsmasher1 Tôi đã chỉnh sửa nhận xét của bạn về câu hỏi của bạn vì đây là một phần thông tin quan trọng! Nếu bạn không hài lòng với nó, hãy tiếp tục và chỉnh sửa nó. –

0

Vì bạn đang hack nặng, dù sao, tại sao không chỉ cần sử dụng một macro

#define fork() (spoon(),fork()) 

hoặc

#define fork() spoon(fork()) 

nơi spoon là sau đó chức năng nào những điều mà bạn muốn đạt được.

Bộ tiền xử lý được đảm bảo không thực hiện đệ quy và để riêng fork bên trong cuộc xâm lược.

+0

vấn đề của tôi không phải là làm thế nào để quá tải ngã ba(). Tôi đã có thể quá tải nó bằng cách sử dụng "dlsym" sys gọi. Vấn đề của tôi là làm thế nào để nhân rộng công việc của ngã ba(), anyways tôi đã có thể đạt được điều đó bây giờ bằng cách sử dụng đề nghị của larsman và vấn đề của tôi được giải quyết. Thatnks anyways. – kingsmasher1

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