我正在尝试用C语言创建一些错误处理代码。我找不到破坏函数的输入:
time(time_t *tloc)
我想模拟 time(( 中断,以便我可以测试我的错误处理代码。我尝试的输入要么通过而没有错误,要么整个程序崩溃(段错误(。我试图产生的一个错误是找不到日历。在这种情况下,time(( 将返回 -1 并将 errno 设置为 14("错误地址"(。我怎么能在没有内核隔离的情况下强制这个结果?
因为现代x86
Linux 内核上的 libc time()
函数是使用 vdso
系统调用实现的(见man 7 vdso
(,我们必须采取一些诡计。
使用vdso
,内核永远不会被输入。这是针对高频、高速的关键呼叫(如time
、gettimeofday
等(完成的。所有活动都在用户空间中进行。 因此,段错误。真正的 [非 vdso] 系统调用将执行检查并返回所需的错误代码。
我们必须使用 syscall(SYS_time,...)
强制进入内核版本的系统调用。
下面是一个示例程序:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/syscall.h>
int opt_t;
int
main(int argc,char **argv)
{
char *cp;
time_t tv;
time_t *tp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 't':
opt_t = 1;
break;
}
}
tp = (time_t *) 0xC0000000;
// this segfaults due to vdso
if (opt_t) {
printf("using time ...n");
tv = time(tp);
}
// this returns error code
else {
printf("using syscall ...n");
tv = syscall(SYS_time,tp);
}
printf("tv=%8.8lX errno=%d -- %sn",tv,errno,strerror(errno));
return 0;
}
强制time()
函数失败的一种方法是在没有RTC(实时时钟(的系统上运行应用程序。 然而,这样的系统也会在几乎所有其他方面失败。