risc-v doubles getting clobbered somehow
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
qemu (Ubuntu) |
Fix Released
|
High
|
Unassigned |
Bug Description
I've been noticing that doubles get clobbered in stress-ng. I managed to whittle it down to the following reproducer that can trip the issue on a risc-v system running the Linux risc-v-qemu 5.4.0-24-generic kernel. This also occurs on other older kernels too. I've tested this with gcc-9, gcc-10 and clang-9 too.
#include <sys/time.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
double timeval_
{
return (double)tv->tv_sec + ((double)
}
int main(void)
{
struct timeval tv2, tv1;
double t1;
bool fail = false;
gettimeofday(&tv1, NULL);
t1 = timeval_
for (;;) {
double t2;
int tmp;
gettimeofday(
t2 = timeval_
tmp = errno;
if (t2 - t1 < 0.0) {
printf("%f %f %f\n", t1, t2, t2 - t1);
printf("START : %f %ld %ld (%lx %lx) errno=%d\n",
t1,
tv1.tv_sec, tv1.tv_usec,
tv1.tv_sec, tv1.tv_usec,
tmp);
printf("NOW BAD: %f %ld %ld (%lx %lx) errno=%d\n",
t2,
tv2.tv_sec, tv2.tv_usec,
tv2.tv_sec, tv2.tv_usec,
tmp);
fail = true;
} else {
if (fail) {
printf("NOW OK: %f %ld %ld (%lx %lx) errno=%d\n",
t2,
tv2.tv_sec, tv2.tv_usec,
tv2.tv_sec, tv2.tv_usec,
tmp);
}
fail = false;
}
}
}
Run the code (compiled with -O0, -O1 or even O2) and after some (long) random-ish time I see:
./a.out
1575050049.059796 0.000000 -1575050049.059796
START : 1575050049.059796 1575050049 59796 (5de15b41 e994) errno=0
NOW BAD: 0.000000 1575050053 437619 (5de15b45 6ad73) errno=0
NOW OK: 1575050053.460829 1575050053 460829 (5de15b45 7081d) errno=0
So the t2 value is zero which is a bit weird. The integer values for the tv struct are sane though, so it appears not to be a bad struct value returned from the kernel.
Changed in qemu (Ubuntu): | |
status: | New → Triaged |
Does this occur on real H/W? Can somebody with risc-v H/W test this out?