I was trying to find where a program was receiving data from a socket. One way to do that is to attach to the program using gdb and creating a catchpoint. You can catch on a specific syscall by running catch syscall recv. When I did that, I got an error along the lines of “no syscall known by that name”.

Initially I just thought that gdb was missing some kind of database that mapped syscall names to the specific syscall number. I went to my syscall page of choice to look up the actual number and was surprised to find that there was no entry for recv.

I quickly went to the man pages to make sure that I wasn’t going insane and remembering syscalls that never existed. A quick man 2 recv showed

RECV(2)                       Linux Programmer's Manual                      RECV(2)

NAME
       recv, recvfrom, recvmsg - receive a message from a socket

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

       ssize_t recv(int sockfd, void *buf, size_t len, int flags);

       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

       ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

man man tells us that section 2 of the man pages documents “System calls (functions provided by the kernel)”. So obviously recv should be a system call that linux implements.

However, if you go look at the source code for musl libc, you see that recv is just a thin wrapper around recvfrom.

It appears that the man pages are not 100% aligned with the actual implementation of linux but document the posix API that linux generally tries to give to users.

All of this is also true for the send syscall which is just a thin wrapper around sendto on linux.