unix 套接字错误 14:EFAULT(错误地址)
我有一个非常简单的问题,但整个周末我都没有找到任何答案。我正在使用 sendto()
函数,它返回错误代码 14:EFAULT。手册页将其描述为:
"An invalid user space address was specified for an argument."
我确信这是在谈论我指定的 IP 地址,但现在我怀疑它可能是它所引用的消息缓冲区的内存地址 - I在任何地方都找不到对此的任何澄清,有人可以澄清吗?
I have a very simple question, but I have not managed to find any answers to it all weekend. I am using the sendto()
function and it is returning error code 14: EFAULT. The man pages describe it as:
"An invalid user space address was specified for an argument."
I was convinced that this was talking about the IP address I was specifying, but now I suspect it may be the memory address of the message buffer that it is referring to - I can't find any clarification on this anywhere, can anyone clear this up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
EFAULT
如果传递给sendto
(或更一般地说,任何系统调用)的某个参数的内存地址无效,就会发生这种情况。将其视为内核空间中与系统调用相关的一种SIGSEGV
。例如,如果您传递一个空或无效的缓冲区指针(用于读取、写入、发送、接收...),您会得到该信息请参阅 errno(3), sendto(2) 等等...手册页。
EFAULT
与 IP 地址完全无关。EFAULT
It happen if the memory address of some argument passed tosendto
(or more generally to any system call) is invalid. Think of it as a sort ofSIGSEGV
in kernel land regarding your syscall. For instance, if you pass a null or invalid buffer pointer (for reading, writing, sending, recieving...), you get thatSee errno(3), sendto(2) etc... man pages.
EFAULT
is not related to IP addresses at all.使用
getcpu
的最小可运行示例为了让事情更具体,我们可以看一下
getcpu
系统调用,它非常容易理解,并显示相同的 EFAULT 行为。从
man getcpu
我们看到签名是:cpu
指向的内存将包含系统调用后进程正在运行的当前CPU的ID,唯一可能的错误是:因此我们可以使用以下命令对其进行测试:
main.c
编译并运行:
示例输出:
因此我们看到垃圾地址为
1
的错误调用返回了14,从内核代码中可以看出这是 EFAULT:https://stackoverflow.com/a/53958705/895245
请记住,系统调用本身返回
-14
,然后syscall
C 包装器检测到由于负数而导致错误,返回-1
并设置errno
为实际的精确错误代码。由于系统调用非常简单,我们也可以从内核 5.4 实现中确认这一点
kernel/sys.c
:我们清楚地看到,如果出现问题,就会返回
-EFAULT
put_user
。值得一提的是,我的 glibc 在 sched.h 中也有一个 getcpu 包装器,但是在地址错误的情况下该实现会出现段错误,这有点令人困惑:<一个href="https://stackoverflow.com/questions/23224607/how-do-i-include-linux-header-files-like-linux-getcpu-h/61774312#61774312">如何包含 Linux 头文件,例如linux/getcpu.h? 但这并不是实际的系统调用对进程所做的事情,而是 glibc 对该地址所做的事情。
在 Ubuntu 20.04、Linux 5.4 上测试。
Minimal runnable example with
getcpu
Just to make things more concrete, we can have a look at the
getcpu
system call, which is very simple to understand, and shows the same EFAULT behaviour.From
man getcpu
we see that the signature is:and the memory pointed to by the
cpu
will contain the ID of the current CPU the process is running on after the syscall, the only possible error being:So we can test it out with:
main.c
compile and run:
Sample output:
so we see that the bad call with a trash address of
1
returned14
, which is EFAULT as seen from kernel code: https://stackoverflow.com/a/53958705/895245Remember that the syscall itself returns
-14
, and then thesyscall
C wrapper detects that it is an error due to being negative, returns-1
, and setserrno
to the actual precise error code.And since the syscall is so simple, we can confirm this from the kernel 5.4 implementation as well at
kernel/sys.c
:so clearly we see that
-EFAULT
is returned if there is a problem withput_user
.It is worth mentioning that my glibc does have a
getcpu
wrapper as well insched.h
, but that implementation segfaults in case of bad addresses, which is a bit confusing: How do I include Linux header files like linux/getcpu.h? But it is not what the actual syscall does to the process, just whatever glibc is doing with that address.Tested on Ubuntu 20.04, Linux 5.4.
EFAULT 是文件“include/uapi/asm-generic/errno-base.h”中定义的宏
EFAULT is a macro defined in a file "include/uapi/asm-generic/errno-base.h"