Mi problema se originó con una biblioteca compartida que me dieron sin la opción de volver a compilar la biblioteca. El error indicó undefined reference to memcpy@GLIBC_2.14 .
La versión de GLIBC en mi máquina era 2.12. He visto arreglos que la gente ha hecho en línea usando la línea
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); La solución que hice fue usar un editor hexadecimal para cambiar la referencia de 2.14 a GLIBC_2.2.5. Al ejecutar el comando readelf -V lib_name.so , las salidas cambiaron de:
0x0060 Name: GLIBC_2.14 Flags: none Version 6 ...... 0x0080 Name: GLIBC_2.2.5 Flags: none Version 4para:
0x0060 Name: GLIBC_2.2.5 Flags: none Version 6 ...... 0x0080 Name: GLIBC_2.2.5 Flags: none Version 4Esto solucionó mi error. Lo que quiero saber es qué efectos tendrá esto. He intentado investigar memcpy vs. memmove y el cambio a memcpy a partir de GLIBC_2.14, pero no entiendo muy bien qué está pasando y cuál era el problema original con memcpy. Me preocupa esta "corrección", aunque permite que mi programa se ejecute, en caso de que lo que sea que esté haciendo memcpy no se comporte correctamente. ¿Por qué todas las correcciones que he visto en línea se relacionan específicamente con la versión 2.2.5?
Agradecería si alguien pudiera darme una idea sobre este tema o proporcionar algunos enlaces con información relevante.
Lo que quiero saber es qué efectos tendrá esto.
El efecto más probable es que la primera vez que su biblioteca de terceros llame a memcpy , se bloquee.
Hay una razón por la que se introdujo una nueva versión de memcpy@GLIBC_2.14 : no es compatible con ABI con el antiguo memcpy (lo que sucedió aquí es que a partir de GLIBC-2.14, memcpy es un GNU_IFUNC , lo que significa que devuelve la dirección de memcpy ; el código en la biblioteca de terceros llamará a la rutina devuelta. Pero el valor de retorno de memcpy@GLIBC_2.2.5 es el parámetro de destino y no una dirección de función, por lo que se espera que se cuelgue de inmediato).
si alguien pudiera darme alguna idea
La biblioteca que le dieron requiere GLIBC-2.14. Al ejecutarlo en una máquina GLIBC-2.12, ha anulado todas las garantías. Tu mejor apuesta es:
Actualizar:
No estoy usando el valor devuelto por memcpy
No entendiste cómo funciona GNU_IFUNC s. Aquí hay una descripción . El problema es que, si bien no está utilizando el valor de retorno, el enlazador dinámico sí lo hace .
El código dentro del enlazador dinámico hace algo como:
if (symbol type == STT_GNU_IFUNC) { // call the IFUNC to get an address of the actual implementation void (*pfun)() = memcpy(); // call the actual (non-IFUNC) implementation of memcpy. return (*pfun)(to, from, size); // You will crash here! } Al sustituir la versión no ifunc por una versión infunc a través de asm hack, garantizaste que pfun == to , y por lo tanto tu to se llamará como si fuera una función. Eso debería normalmente SIGSEGV inmediatamente.