【发布时间】:2023-01-08 07:19:42
【问题描述】:
在Android 12手机中执行的程序中的以下代码:
struct timeval tv;
int ret = gettimeofday(&tv, NULL);
if (ret < 0)
printf("gettimeofday failed with %s\n", strerror(errno));
printf("%lu.%ld\n", tv.tv_sec, tv.tv_usec);
回报
gettimeofday failed with Value too large for defined data type
1078605538.1
此外,seconds 和 useconds 始终保持不变,即使在循环内调用也是如此。
使用 clock_gettime(CLOCK_REALTIME, &tv); 得到完全相同的结果
一定是出了什么问题,因为根据联机帮助页,gettimeofday() 不应该返回 errno 75。
跟踪输出:
read(3, " \0\0\0\1\0\0\0\273\0\0\0\230\1\0\0\1\0\0\0\20\0\254\0\254\0\223\261zG\377F"..., 65536) = 199
clock_gettime(CLOCK_REALTIME, {tv_sec=3416400658881740019, tv_nsec=4632575514938983213}) = 0
dup(2) = 4
fcntl64(4, F_GETFL) = 0x20002 (flags O_RDWR|O_LARGEFILE)
statx(4, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS, stx_attributes=0, stx_mode=S_IFCHR|0600, stx_size=0, ...}) = 0
write(4, "gettimeofday: Value too large fo"..., 52gettimeofday: Value too large for defined data type
) = 52
close(4)
[ and same repeats, we are in a loop ]
【问题讨论】:
-
1078605538回到 2004 年的某个时候,但是大概这只是一堆垃圾。如果您在gettimeofday调用之前立即添加memset(&tv, 0, sizeof tv),是否会改为打印0.0? -
我还要仔细检查系统时钟是否实际设置正确;这可能是某种健全性检查,类似于“如果时钟设置为 Android 12 发布之前的日期,则一定有问题”。
-
gettimeofday内部调用的东西可能返回 -1,但被转换为无符号整数,这可能使其看起来非常大。这是设置errno的东西。请记住,errno是全局的。 -
好的,接下来我要尝试的是在
strace下运行该程序。 (这会产生几百行输出,我们需要看最后的30 行左右。) -
这是一些令人费解的
strace输出:clock_gettime返回0(我假设这是gettimeofdaylibc 包装器调用的),但是你检查errno而不是0... 有什么东西坏了.另外,stdout的 fd 是否以某种方式4?或者你在别的地方写?这很奇怪。您确定那正是您正在运行的代码吗?例如。如果你只把那几行放在int main(void)中并运行它,你会得到相同的结果吗?