Что происходит с параметрами execv?

Я всегда был немного туманен в этом маленьком волшебстве C. Когда вы вызываете execv, вы «заменяете образ процесса». Что именно это значит? Только сегмент DATA? Все, что выделено для процесса? Стек? Куча?

Мой вопрос о том, что происходит с хранилищем, используемым параметрами, которые вы передаете в execv? Если они были локальными переменными для функции, вызвавшей execv, то они находятся в стеке. Но если вы замените образ процесса и вызовете функцию main() нового процесса, при возвращении функции main() произойдут плохие вещи, потому что информация стека, указывающая на место возврата из основного вызова, была заменена новым образом процесса. То же самое для переменных, да? А что, если бы эти переменные были размещены в куче?

Пытливые умы спрашивают любого, кто знает.


person stu    schedule 06.12.2015    source источник
comment
Я думаю, что это может быть лучший ответ.   -  person Punit Vara    schedule 06.12.2015
comment
Официальная документация для вас: pubs.opengroup.org/onlinepubs/9699919799/functions /exec.html   -  person alk    schedule 06.12.2015
comment
ОС требуется для настройки нового адресного пространства, чтобы все, что нужно программе для запуска, было доступно, что может включать копирование параметров.   -  person Alan Stokes    schedule 06.12.2015
comment
Нет такой вещи, как место возврата из основного звонка. Когда main возвращается, программа завершается.   -  person interjay    schedule 06.12.2015


Ответы (2)


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

То, что происходит с параметрами, которые вы передали, является проблемой ОС - она ​​должна убедиться, что они переданы в функцию main нового процесса в соответствии со стандартом, но я не думаю, что POSIX диктует, как именно он это делает. .

Для Linux вы можете посмотреть fs/exec.c файл, чтобы увидеть реализацию. Перейдите ближе к концу (строка 1484, когда я публикую это), чтобы посмотреть на функцию do_execveat_common, которая является основной частью реализации. Вы увидите, что аргументы скопированы в новое адресное пространство (вызовы copy_strings ближе к концу функции).

person Mat    schedule 06.12.2015

Только сегмент DATA?

Нет, все сопоставления памяти стираются и создаются заново для нового исполняемого файла.

Все, что выделено для процесса? Стек? Куча?

Да, вся память. Однако некоторые ресурсы ядра, задокументированные здесь, наследуются от родительского процесса, например файловые дескрипторы. Эти ресурсы управляются ядром и не являются частью памяти процесса. Все это довольно специфично для операционной системы, однако это можно сделать с помощью различных средств, если это соответствует упомянутой документации exec().

что происходит с хранилищем, используемым параметрами, которые вы передаете в execv?

Обычно ядро ​​делает копию этих аргументов и вводит их в память нового исполняемого файла.

Но если вы замените образ процесса и вызовете функцию main() нового процесса, при возвращении функции main() произойдут плохие вещи,

Нет, когда main() возвращается, этот процесс завершается. Код и память исходного процесса, вызвавшего exec(), больше не существуют, возвращаться не к чему.

person nos    schedule 06.12.2015
comment
Верно, это то, что я имел в виду под плохими вещами. Я просто не получил разрыв между хранилищем параметров, переданных в новую вселенную, где старая вселенная исчезла. - person stu; 06.12.2015