Estaba leyendo la documentación de GNU sobre la opción --wrap del enlazador GCC, que se puede usar para simular funciones para realizar pruebas.
https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html dice lo siguiente:
--símbolo de envoltura
Use una función de envoltura para el símbolo. Cualquier referencia indefinida al símbolo se resolverá como __wrap_symbol. Cualquier referencia indefinida a __real_symbol se resolverá como símbolo. Esto se puede utilizar para proporcionar un contenedor para una función del sistema. La función contenedora debe llamarse __wrap_symbol. Si desea llamar a la función del sistema, debe llamar a __real_symbol.
Me di cuenta de que dice Cualquier referencia indefinida al símbolo se resolverá en __wrap_symbol , pero no dice qué significa exactamente una referencia indefinida al símbolo . ¿Alguien sabe específicamente lo que se considera indefinido ?
Estoy confundido porque creé un programa de ejemplo que simula con éxito la función de read (se compila con gcc test.c -o test -Wl,--wrap=read para habilitar la simulación). ¿Cómo es que el enlazador considera este símbolo indefinido? unistd.h , entonces, ¿no debería eso hacer que la read esté definida? Pensé que la documentación decía: --wrap solo funciona en símbolos indefinidos?
#include <stdio.h> #include <string.h> #include <unistd.h> #define DUMMY_STR "I don't care because this function is mocked." #define DUMMY_LEN (strlen(DUMMY_STR)) ssize_t __wrap_read(int fd, void *buf, size_t count) { sprintf(buf, DUMMY_STR); return DUMMY_LEN; } int main() { char buf[128] = {'\0'}; puts("Press anything, then ENTER, to continue"); read(1, buf, sizeof(buf) - 1); puts(buf); return 0; }Incluir el archivo de encabezado solo declara los símbolos, no los define ; no estarán definidos en su unidad de compilación test.c porque nunca los define.
De hecho, el símbolo de lectura está definido en libc.so, la biblioteca estándar de C, pero al vincular su programa, primero ve su unidad de compilación (test.o), momento en el que la lectura aún no está definida . Entonces, las referencias para read se asignan a __wrap_read .
definiciones y declaraciones son dos cosas diferentes. Relacionados, pero diferentes.