Я думаю, что процесс запуска программы Linux, использующей разделяемую библиотеку (не скомпилированную с помощью -static), выглядит следующим образом:
(1) Введите имя исполняемого файла в bash
(2) Bash прочитал исполняемый файл и обнаружил, что он содержит секцию .interp, которая содержит имя динамического загрузчика.
(3) Bash разветвляет новый процесс, и в подпроцессе запускает динамический загрузчик и передает имя / путь исполняемого файла в качестве параметра динамическому загрузчику. Но я не уверен, как называется точка входа, в динамическом загрузчике нет _start, который /lib64/ld-linux-x86-64.so.2
(4) После возврата exec из ядра Linux в пользовательский режим первая инструкция, выполняемая в пользовательском режиме, должна быть точкой входа в динамический загрузчик.
(5) Динамический загрузчик загружает исполняемый файл (имя / путь которого передается в качестве параметра) и все его зависимости, а динамический загрузчик будет вызывать методы в разделе .init_array каждого загруженного модуля. В частности, методы в разделе .init_array в основном исполняемом файле также должны выполняться динамическим загрузчиком. Действительно, с точки зрения динамического загрузчика нет большой разницы между основным исполняемым файлом и разделяемыми библиотеками.
(6) Динамический загрузчик вызывает точку входа основного исполняемого файла _start. Это означает, что если точка входа динамического загрузчика также называется _start, с этого момента в стеке вызовов должно быть два _start.
Есть ли какие-либо проблемы в понимании вышеизложенного?
Но проблема в том, что при отладке программы с помощью gdb и использовании
set backtrace past-main
start
bt
Он показывает только обратную трассировку до _start, но как насчет стеков вызовов в динамическом загрузчике? Также пробовал:
set backtrace past-entry
start
bt
Теперь он ничего не показывает перед main ...