2011-02-02 2 views
6

Я перегрузил системный вызов fork() и создал свою собственную версию fork() с использованием RTLD_NEXT. То есть, dlsym(RTLD_NEXT, fork). Это ударит по моей версии вилки. После этого я хочу реплицировать задачу фактического fork() системного вызова, то есть создания дочернего процесса и возврата pid и еще нескольких дополнительных функций.Перегрузка вилки()

Я не могу понять, как это сделать. Я проверил исходный код ядра для fork() (fork.c) и не мог понять много.

Делать это:

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

Как я могу это сделать? Вот ссылка на ядро ​​исходного кода для вилки: http://lxr.linux.no/linux+v2.6.32/kernel/fork.c#L10

Edit (вытянуто в от комментариев):

Я работаю над утечкой обнаружением инструмента, и этот инструмент обнаруживает двойной свободным когда дочерний процесс удаляет память, выделенную родителем. Чтобы преодолеть это, я переопределяю fork(), и всякий раз, когда есть fork(), таблица распределения памяти родителя будет дублироваться с дочерним элементом.

+0

Что вы подразумеваете под "не работает"? Ошибки времени выполнения? Ошибки компилятора? – Simone

+0

@ Симоне: _fork(); // Ошибка: _fork не был объявлен. Моя идея состояла в том, чтобы поразить фактическую версию ядра вилки, а не мою. Надеюсь, теперь это ясно. – kingsmasher1

+0

Что именно вы хотите сделать, выполнив это? Какова ваша конечная цель? – Omnifarious

ответ

3

Вы должны иметь возможность позвонить по телефону fork с помощью syscall(SYS_fork) после включения <sys/syscall.h>. См. syscall(2).

+0

Я не был уверен, что действительно существует системный вызов 'fork'. Я думал, что он был переведен на вызов «clone» с определенным набором параметров. – Omnifarious

+0

@larsmans: Это дает хорошую идею! Отлично. Позвольте мне попробовать это сейчас и посмотреть, работает ли оно. – kingsmasher1

+0

@Omnifarious: он все еще работает. Наверное, наоборот. –

7

Вы не получите ничего полезного из исходного кода ядра для fork. Вашему коду не будет разрешено делать то, что ядро ​​делает независимо от того, какую библиотеку вы обходите. Это жесткая граница, которая не может быть нарушена без написания модуля ядра.

Весь код библиотеки для fork действительно задает вещи и выполняет специальную инструкцию, которая переключается в режим ядра, где выполняется код ядра fork. Существует своего рода способ поместить эту специальную инструкцию в свой собственный код. Это функция syscall. Поскольку fork не принимает никаких аргументов, для выполнения системного вызова относительно просто использовать эту функцию.

Но это не то, что я рекомендую вам сделать. Я рекомендую вам сделать это вместо:

typedef int (*forkfunc_t)(void); 

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

В принципе, независимо от разделяемой библиотеки повозки, запряженных волов вы делаете, вы должны в основном найти способ извлечения предыдущего значения функции fork, прежде чем заменить его самостоятельно.

+0

Я работаю над инструментом обнаружения утечки, и этот инструмент обнаруживает двойной доступ, когда дочерний процесс удаляет память, выделенную родителем. Чтобы преодолеть это, я переопределю fork(), и всякий раз, когда есть fork(), таблица распределения памяти родителя будет дублирована для дочернего элемента. – kingsmasher1

+0

@ kingsmasher1: Ahh, поэтому вам не нужно изменять то, что делает ядро ​​с 'fork', вам просто нужно убедиться, что вы перехватите его и соответствующим образом заверните. Это очень удобно, и ваша общая библиотечная техника не так уж плоха в том, как это сделать. – Omnifarious

+0

@ kingsmasher1 Я отредактировал ваш комментарий к вашему вопросу, поскольку это довольно важная информация! Если вы недовольны этим, сделайте это и отредактируйте. –

0

Поскольку вы хакерство плохо, во всяком случае, почему бы не просто использовать макрос

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

или

#define fork() spoon(fork()) 

где spoon тогда функция, которая делает то, что вы хотите достичь.

Препроцессор гарантированно не выполняет рекурсию и оставляет fork внутри экспатриации.

+0

моя проблема не было, как перегрузить fork(). Я смог перегрузить его, используя вызов «dlsym» sys. Моя проблема заключалась в том, как копировать работу fork(), так или иначе, я смог достичь этого, используя предложение larsman, и моя проблема решена. В любом случае. – kingsmasher1

Смежные вопросы