c - Linux 系统调用何时触发段错误与返回 EFAULT?

标签 c linux error-handling system-calls vdso

我试图了解 clock_gettime() 何时会导致错误。手册页列出了以下两种可能性:

  1. EFAULT tp 指向可访问地址空间之外。
  2. EINVAL 此系统不支持指定的 clk_id。

很容易触发 EINVAL 错误,但我无法让 clock_gettime()errno 设置为 EFAULT 。相反,内核会发送一个 SIGSEGV 信号来终止程序。例如,在下面的代码中:

#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
    struct timespec tp;
    double time;

    if (clock_gettime(CLOCK_MONOTONIC, &tp + 4096) == -1) {
        if (errno == EINVAL) {
            perror("EINVAL");
            return EXIT_FAILURE;
        } else if (errno == EFAULT) {
            perror("EFAULT");
            return EXIT_FAILURE;
        } else {
            perror("something else");
            return EXIT_FAILURE;
        }
    }

    time = tp.tv_sec + 1e-9 * tp.tv_nsec;
    printf("%f\n", time);
}

Linux 内核如何在触发段错误和让系统调用返回 -EINVAL 之间做出选择?它什么时候会选择做后者?如果内核总是发送信号,是否真的需要检查errno是否等于EFAULT

我正在运行 Linux 内核 4.15 并使用(使用 clang v6.0)编译程序: clang -g -O0 -Wall -Wextra -Wshadow -Wstrict-aliasing -ansi -pedantic -Werror -std=gnu11 file.c -o file

最佳答案

clock_gettime 可能不作为系统调用执行,而是作为 vdso 的一部分在用户空间中执行.如果您实际使用以 SYS_clock_gettime 作为参数的 syscall 函数执行系统调用,我希望您看到 EFAULT

话虽如此,EFAULT 并不是您应该期望能够依赖的东西。一旦将无效指针传递给需要有效指针作为其接口(interface)协定的一部分的函数,就会出现未定义的行为,段错误或错误只是众多表现形式中的一种可能。从这个角度来看,甚至记录了 EFAULT 也是一个错误。

关于c - Linux 系统调用何时触发段错误与返回 EFAULT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53384022/

相关文章:

python - 如何使Kivy ActionBar Button在单击时执行某些操作?

c - 在结构体数组后打印字符

c - "the start of an allocated memory block"在这里意味着什么?

c - C中定义的数组类型

c - 从哪里开始修改开源软件?

linux - 我怎样才能创建一个假的设备文件来模仿 dev/mem?

android - Android New文物跟踪非网络错误

c - Linux 中是否存在用户级可访问字体表?

c++ - Linux中getlogin函数的使用

mongodb - 根据类型处理MongoDB错误