En las strace
salidas, las rutas a las bibliotecas a las que llaman los ejecutables están en llamadas a open()
. ¿Es esta la llamada al sistema utilizada por ejecutables que están vinculados dinámicamente? ¿Qué hay de dlopen()
? open()
No es una llamada que supuse que jugaría un papel en la ejecución de programas.
23
ld-linux
el núcleo los asigna como parte de laexecve
llamada al sistema.dlopen no tiene nada que ver con las bibliotecas compartidas como piensas en ellas. Hay dos métodos para cargar un objeto compartido:
main
función, y configurará el espacio de proceso de la aplicación para que la aplicación encuentre las funciones de la biblioteca. Esto implicaopen()
incorporar el lubrary, y luegommap()
ing, seguido de la configuración de algunas tablas de búsqueda.libdl
, desde el cual puede (usando el primer método) llamar aldlopen()
ydlsym()
funciones Con dlopen obtienes un identificador de la biblioteca, que luego puedes usar con dlsym para recibir un puntero de función a una función en particular. Este método es mucho más complicado para el programador que el primer método (ya que debe hacer la configuración manualmente, en lugar de que el enlazador lo haga automáticamente por usted), y también es más frágil (ya que no obtiene la compilación -time comprueba que está llamando a funciones con los tipos de argumento correctos a medida que obtiene el primer método), pero la ventaja es que puede decidir qué objeto compartido cargar en tiempo de ejecución (o incluso si cargarlo en absoluto), haciendo Esta es una interfaz destinada a la funcionalidad de tipo de complemento. Finalmente, la interfaz dlopen también es menos portátil que la otra manera, ya que su mecánica depende de la implementación exacta del enlazador dinámico (de ahí que libtool'slibltdl
, que intenta abstraer estas diferencias).fuente
Hoy, la mayoría de los sistemas operativos usan el método para bibliotecas compartidas introducido a fines de 1987 por SunOS-4.0. Este método se basa en la memoria de mapeo a través de mmap ().
Dado el hecho de que a principios de la década de 1990, Sun incluso donó el antiguo código basado en a.out (Solaris en ese momento ya estaba basado en ELF) a las personas de FreeBSD y que este código luego se entregó a muchos otros sistemas (incluido Linux) , puede entender por qué no hay una gran diferencia entre plataformas.
fuente
ltrace -S
El análisis de un ejemplo mínimo muestra quemmap
se usa en glibc 2.23En glibc 2.23, Ubuntu 16.04, ejecutándose
latrace -S
en un programa mínimo que utilizadlopen
con:muestra:
entonces vemos de inmediato que las
dlopen
llamadasopen
+mmap
.La asombrosa
ltrace
herramienta rastrea las llamadas a la biblioteca y las llamadas al sistema, y por lo tanto es perfecta para examinar lo que está sucediendo en este caso.Un análisis más detallado muestra que
open
devuelve el descriptor de archivo3
(el siguiente libre después de stdin, out y err).read
luego usa ese descriptor de archivo, pero TODO por quémmap
los argumentos están limitados a cuatro, y no podemos ver qué fd se utilizó allí ya que ese es el quinto argumento .strace
confirma como se esperaba que ese3
es, y el orden del universo se restaura.Las almas valientes también pueden aventurarse en el código glibc, pero no pude encontrar el
mmap
después de un grep rápido y soy flojo.Probado con este ejemplo mínimo con build boilerplate en GitHub .
fuente
strace
informes sobre llamadas del sistema (es decir, funciones implementadas directamente por el núcleo). Las bibliotecas dinámicas no son una función del núcleo;dlopen
es parte de la biblioteca C, no el núcleo. La implementación dedlopen
will llamaráopen
(que es una llamada al sistema) para abrir el archivo de la biblioteca y poder leerlo.fuente
ltrace
.ltrace -S
es perfecto para analizar esto, ya que también muestra syscalls: unix.stackexchange.com/a/462710/32558