【发布时间】:2019-04-22 08:48:40
【问题描述】:
我试图了解clock_gettime() 何时会导致错误。手册页列出了以下两种可能性:
- EFAULT tp 指向可访问地址空间之外。
- 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
【问题讨论】:
-
我不相信系统调用会出现段错误。但是glibc可以segfault,很多你以为是系统调用的函数其实都是glibc函数。
标签: c linux error-handling system-calls vdso