GNU/Linux >> Tutoriales Linux >  >> Linux

Vinculación con una versión anterior de libc para proporcionar una mayor cobertura de aplicaciones

Averigüe qué símbolos en su ejecutable están creando la dependencia de la versión no deseada de glibc.

$ objdump -p myprog
...
Version References:
  required from libc.so.6:
    0x09691972 0x00 05 GLIBC_2.3
    0x09691a75 0x00 03 GLIBC_2.2.5

$ objdump -T myprog | fgrep GLIBC_2.3
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3   realpath

Mire dentro de la biblioteca de la que depende para ver si hay algún símbolo en versiones anteriores con el que pueda vincular:

$ objdump -T /lib/libc.so.6 | grep -w realpath
0000000000105d90 g    DF .text  0000000000000021 (GLIBC_2.2.5) realpath
000000000003e7b0 g    DF .text  00000000000004bf  GLIBC_2.3   realpath

¡Estamos de suerte!

Solicite la versión de GLIBC_2.2.5 en tu código:

#include <limits.h>
#include <stdlib.h>

__asm__(".symver realpath,[email protected]_2.2.5");

int main () {
    realpath ("foo", "bar");
}

Observe que GLIBC_2.3 ya no es necesario:

$ objdump -p myprog
...
Version References:
  required from libc.so.6:
    0x09691a75 0x00 02 GLIBC_2.2.5

$ objdump -T myprog | grep realpath
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 realpath

Para obtener más información, consulte http://web.archive.org/web/20160107032111/http://www.trevorpounds.com/blog/?p=103.


Desafortunadamente, la solución de @Sam no funciona bien en mi situación. Pero de acuerdo con su manera, encontré mi propia manera de resolver eso.

Esta es mi situación:

Estoy escribiendo un programa C++ usando el marco Thrift (es un middleware RPC). Prefiero el enlace estático al enlace dinámico, por lo que mi programa está vinculado a libthrift.a estáticamente en lugar de libthrift.so . Sin embargo, libthrift.a está vinculada dinámicamente a glibc, y desde mi libthrift.a está construido en mi sistema con glibc 2.15, mi libthrift.a usa memcpy de la versión 2.14([email protected]_2.14 ) proporcionado por glibc 2.15.

Pero el problema es que nuestras máquinas servidor solo tienen la versión 2.5 de glibc que solo tiene [email protected]_2.2.5 . Es mucho más bajo que [email protected]_2.14 . Entonces, por supuesto, mi programa de servidor no puede ejecutarse en esas máquinas.

Y encontré esta solución:

  1. Usando .symver para obtener la referencia a [email protected]_2.2.5 .

  2. Escribir mi propio __wrap_memcpy función que simplemente llama a [email protected]_2.2.5 directamente.

  3. Al vincular mi programa, agregue -Wl,--wrap=memcpy opción a gcc/g++.

El código involucrado en los pasos 1 y 2 está aquí:https://gist.github.com/nicky-zs/7541169


Linux
  1. Ubuntu:¿la versión de Pango-error Harfbuzz es demasiado antigua?

  2. Fedora:¿forzar a Dnf a instalar una versión anterior de un paquete?

  3. ¿Instalar la versión 1.5 o superior de Vagrant en la 14.10?

  4. Advertencia de libpng:versión de libpng incompatible en la aplicación y la biblioteca

  5. Vinculación con una versión de símbolo anterior en un archivo .so

Cómo degradar una aplicación o un paquete en Ubuntu

DF-SHOW:un administrador de archivos de terminal basado en una antigua aplicación de DOS

Cómo saber la versión de la aplicación antes de instalar en Ubuntu

cómo configurar centos 8 para que arranque con la versión antigua del kernel

¿Cuál es el significado de Advertencia:vincular la biblioteca compartida con la biblioteca estática no es portátil?

¿Comprar la versión anterior de Windows ahora y obtener la actualización de forma gratuita?