From: Tom I. H. <ti...@ha...> - 2013-07-11 18:46:52
|
Josh Elsasser <jo...@el...> writes: > It is mystifying to me that changing struct timeval and timespec to > the correct 64-bit time_t type would break the build on a 64-bit > time_t system. I'll have to set up a netbsd box and take a look at > what's going on. I've got a bit more of a handle on it, now. As it turns out, the crashes are because data returned by get-time-of-day (and unix-fast-getrusage, as well) are wrong, and break assertions. After much experimentation down the wrong paths, I changed both of them to return fake, but good, data, in addition to the bad bits. Here's the relevant part of get-time-of-day: (defvar *fake-tod-value* 1373538840) [...] (defun get-time-of-day () [...] (with-alien ((tv (struct timeval))) (syscall* ("gettimeofday" (* (struct timeval)) (* (struct timezone))) (values (incf *fake-tod-value*) 0 (slot tv 'tv-sec) (slot tv 'tv-usec)) (addr tv) nil)) Note that I've extended it from returning two values to returning four, where the first two are fake, and the last two are the original ones that don't work. With this modification, I got sbcl, checked out at the exact commit where the groveling for the timeval structure and time_t were introduced, to actually build and run. Look at this: * (get-time-of-day) 1373539778 0 365185262860240 65539 * (get-time-of-day) 1373539780 0 1029543689107410 65539 * (get-time-of-day) 1373539782 0 1783984759420882 65539 * (get-time-of-day) 1373539784 0 1134315121326035 65539 * (get-time-of-day) 1373539786 0 1650935262525396 65539 * (get-time-of-day) 1373539788 0 2416191060490197 65539 Note that tv-sec is much too large, and keeps varying immensely, while tv-usec is stuck at the same value all the time. We see why here: * (format t "~X" 365185262860240) 14C2251DEB7D0 NIL * (format t "~X" 1029543689107410) 3A85D51DEB7D2 NIL * (format t "~X" 1783984759420882) 6568651DEB7D2 NIL * (format t "~X" 1134315121326035) 407A751DEB7D3 NIL * (format t "~X" 1650935262525396) 5DD8451DEB7D4 NIL * (format t "~X" 2416191060490197) 8958351DEB7D5 NIL It's rather obvious that the lower 32 bits of the tv-sec value is the proper value (the 51DE.... subsequence is the correct number of seconds since the epoch), while the upper 32 bits vary wildly. I would hazard a guess that the upper 32 bits are actually the tv-usec value: note that they always present a legal value for it. The proper tv-usec slot doesn't get updated, and probably just contains random garbage. Since this works on NetBSD/amd64, I would (really intuitively, with no actual basis) guess that it comes down to the use of "long" somewhere in the C code, which is 32 bits on NetBSD/i386, 64 bits on NetBSD/amd64. Any ideas, before I start trying to understand the underlying C code? -tih -- It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong. -Richard Feynman |