2016-03-02 2 views
0

Я пишу службу (т. Е. Фоновый процесс) и предлагаю начать ее через общую библиотеку. То есть, кто-то, кто хочет использовать эту услугу, будет ссылаться на общую библиотеку, вызовите метод start(), который будет вилкой и возвратом. Затем вилка запускает службу.fork() и освободить всю выделенную память

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

  • , что мне нужна исполняемый файл, который не может быть в том месте, я ожидаю, что это из-за различные макеты папок операционной системы
  • что мне пришлось бы передать все потенциальные параметры в строку, чтобы передать ее в качестве аргументов программы для exec().

Поэтому в основном я ищу способ вызвать произвольную функцию FUNC() с некоторыми параметрами, которые должны выполняться в новом процессе, и все, что не прошло в этой функции не должно быть в новый процесс. Есть ли способ достичь этого или чего-то подобного?

+1

Это, как правило, не нужно, поскольку Linux использует реализацию fork-on-write fork, так что родительский и дочерний ресурсы разделяют «скопированную» память до тех пор, пока ребенок не изменяет ее. –

+1

То, что вы хотите, на самом деле невозможно.Например, предположим, что библиотека использует stdio, а stdio имеет выделенную память, вы не хотите, чтобы ваша «свободная вся выделенная память» освобождала это. Так что вы действительно хотите «освободить все, что больше не нужно», но как может функция общего назначения узнать, что не нужно? – Barmar

+1

@RossRidge Но вы хотели бы удалить свою ссылку на копию, так что все это исчезнет, ​​когда родитель выйдет. – Barmar

ответ

3

Это интересный вопрос, на который у меня, к сожалению, нет хорошего ответа. Я сомневаюсь, что любые стратегии очистки, такие как sbrk + close + munmap, будут надежно разрешать любой код на основе libc продолжать функционировать, поэтому я попытаюсь сделать exec'ing лучше:

Для любого решения на основе Exec вы должны быть способный глубоко копировать данные в shm для передачи нестрочных. Это должно позаботиться о вашей второй проблеме.

Вот некоторые дикие предложения для вашего первого вопроса:

  1. Не: просто требует, чтобы исполняемый файл находится в PATH или директории компиляции.

    Это прозрачно и соответствует философии UNIX. Сообщение об ошибке Can't find myhelper in PATH никого не замедлит. Большинство инструментов в зависимости от вспомогательных исполняемых файлов делают это, и все в порядке.

  2. Make your library executable, и использовать это как цель вашего exec. Вы можете попробовать найти его имя с какой-то интроспекцией, возможно, /proc/self/maps или любыми предложениями glibc.

  3. Как и выше, но exec python или что-то, что вы можете быть разумно уверены, и использовать интерфейс внешнего указателя для запуска функции в своей библиотеке.

  4. Как часть процесса сборки, скомпилируйте крошечный исполняемый файл и включите его в виде двоичных данных в своей библиотеке. Напишите его на /tmp и выполните.

Из этого я предпочитаю простоту и прозрачность # 1, даже если это самое скучное решение.

+0

Спасибо. Я не хочу полагаться на PATH, потому что это критически важное приложение для безопасности и кто знает, где на пути злоумышленник может разместить альтернативный исполняемый файл (например, ~/bin). Однако один из других моментов может работать. О вызове * exec * я передам конфиденциальные данные в исполняемый файл (например, пароли). Будут ли они тогда видны при вызове * ps *, если я передам их в * exec *? – Heinzi

+1

Вы всегда можете дезинфицировать свой путь, люди с правом на запись в '/ sbin' и'/usr/sbin' уже имеют систему pwned. Любые данные, передаваемые ключом через 'shm_open', будут иметь разрешения, которые вы укажете в этом вызове. Другие пользователи не могут использовать 'ps' или что-то еще, чтобы прочитать его, даже если у них есть ключ. –

+0

Спасибо. Звучит хорошо. – Heinzi

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