Перегрузочная вилка () - PullRequest
       42

Перегрузочная вилка ()

6 голосов
/ 02 февраля 2011

Я перегрузил системный вызов 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;
}

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

Редактировать (извлечено из комментариев) :

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

Ответы [ 3 ]

7 голосов
/ 02 февраля 2011

Вы не получите ничего полезного из исходного кода ядра для 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, прежде чем заменить его своим собственным.

3 голосов
/ 02 февраля 2011

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

0 голосов
/ 02 февраля 2011

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

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

или

#define fork() spoon(fork())

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

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

...