Search code examples
cgcclinker-errorsldundefined-reference

Linker error with intercepting function calls in GCC


I am using the standard __wrap_function and __real_function to intercept function calls with -Wl,--wrap=function. This works successfully for most functions like malloc, fopen, etc. However, I am unable to wrap these two functions:

  1. int connect(int, const struct sockaddr*, socklen_t)
  2. int stat(const char*, struct stat*)

With these functions, the linker complains with undefined reference to __real_connect and __real_stat.

Is there any particular reason for this? (Note: I can also wrap socket functions for example)


Solution

  • It is likely you forgot to add -Wl,--wrap=connect and -Wl,--wrap=stat to your link line.

    This works for me:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int __wrap_connect (int s, const struct sockaddr *addr, socklen_t len)
    {
        puts(__func__);
        return __real_connect(s, addr, len);
    }
    
    int __wrap_stat (const char *path, struct stat *buf)
    {
        puts(__func__);
        return __real_stat(path, buf);
    }
    
    int main(void) {
        connect(0, NULL, 0);
        stat("/", 0);
        return 0;
    }
    

    When compiled on my system.

    $ uname -s -r
    Linux 2.6.32-696.16.1.el6.x86_64
    $ gcc --version | grep gcc
    gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
    $ gcc c.c -Wl,--wrap=connect -Wl,--wrap=stat
    $
    

    However, when leaving off -Wl,--wrap=stat, for example, I get:

    $ gcc c.c -Wl,--wrap=connect
    /tmp/cchVzvsE.o: In function `__wrap_stat':
    c.c:(.text+0x65): undefined reference to `__real_stat'
    collect2: ld returned 1 exit status
    $