gccg++ldsendto

Neither ld wrap nor LD_PRELOAD working to intercept system call


I am trying to use -Wl, -wrap=sendto -Wl, -wrap, sendto in my final g++ link command that links my app to replace the standard sendto function with my own.

I compile the following source code with:

gcc -c -o wrap.o wrap.c

and include the wrap.o in the final g++ command that links the app (the rest of the app is C++ hence the use of g++):

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>

ssize_t __real_sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);

ssize_t __wrap_sendto
(
    int sockfd,
    const void *buf,
    size_t len,
    int flags,
    const struct sockaddr *dest_addr,
    socklen_t addrlen
)
{
    printf("my wrap sendto ...\n");
    return __real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}

When I use sendto in my own source code, the wrapper is in fact used ok but all 3rd party shared objects i linked against in my final g++ command that use sendto still use the system sendto i.e. not my wrapper. How can I get my sendto wrapper used throughout?

I have also tried an LD_PRELOAD approach with a sendto and dlsym(RTLD_NEXT) inside but that did not work either.

How can I figure out why the 3rd party library keeps on using the libc sendto directly?

When I use ldd to find all shared object dependencies of my compiled app and then objdump -T on each one of them grepping for sendto, I get UND (undefined) for all the 3rd party shared objects. The shared objects that do define it however is:

/lib64/libpthread.so.0
000000000000ed80  w   DF .text  0000000000000064  GLIBC_2.2.5 sendto
/lib64/libc.so.6
00000000000e98d0  w   DF .text  0000000000000064  GLIBC_2.2.5 sendto

I see in glibc sendto.c on git the following:

weak_alias (__libc_sendto, sendto)
weak_alias (__libc_sendto, __sendto)

Solution

  • I have eventually managed to figure out what was going on here. Even though the strace states sendto is being called:

    [pid 17956] sendto(4, "abc"..., 2052, 0, NULL, 0) = 2052  
    

    what was in fact happening was send(...) was being called (probably possible because 0, null, 0 last three parameters). The moment I made an interceptor for send(...) it worked.