JDK-6452176 : Solaris os::javaTimeMillis() passes bad value to gettimeofday()
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P5
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2006-07-24
  • Updated: 2012-10-08
  • Resolved: 2006-11-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u4Fixed 7Fixed hs10Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b90)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b90, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Any Solaris

A DESCRIPTION OF THE PROBLEM :
hotspot/src/os/solaris/vm/os_solaris.cpp contains this:

jlong os::javaTimeMillis() {
  timeval t;
  static const char* aNull = 0;
  if (gettimeofday( &t, &aNull) == -1)

Two similar calls can be found in hotspot/src/os/solaris/vm/hpi_solaris.hpp.

The second argument to gettimeofday() call should be NULL or a "struct timezone *". What is being passed is "&aNull", i.e. a pointer to a char*. Notice carefully: a NULL is not being passed, but rather a pointer to a variable that contains NULL. Should be aNull or more simply NULL.

As "struct timezone" contains two "int"s (= 8 bytes) and a pointer to a "char*" (= 4 bytes) is passed this is working by sheer luck. I guess the compiler happens to align the stack in such a way that there is extra 4 bytes of space in just the right place. Or maybe the timeval and timezone structs end up partly overlapping. I'm amazed System.currentTimeMillis() isn't dumping core.


REPRODUCIBILITY :
This bug can be reproduced always.

Comments
EVALUATION The second argument to gettimeofday is a historical relic from BSD. While BSD took a "struct timezone*" it has been adapted in XPG4/POSIX and hence Solaris to simply be a "void*". Other definitions removed the second arg completely and Solaris can offer that version too (see comments in /usr/include/sys/time.h). The POSIX/XPG specification states: If tzp is not a null pointer, the behavior is unspecified. While if you consult the solaris manpage (dated 2003 for Solaris 10) for solaris's implementation of gettimeofday it states: The tzp argument to gettimeofday() and settimeofday() is ignored. Curiously (erroneously I guess - it's dated 1993!) the online Solaris manuals still refer to the a "struct timezone *" but also include the text: "tzp is an obsolete pointer formerly used to get and set timezone information. tzp is now ignored. " http://docs.sun.com/app/docs/doc/816-5168/6mbb3hrd7?a=view Consequently while the code is quite bizarre and obviously not doing what the author intended, it is in fact quite harmless on Solaris. (Note the code is simply taking the address of a static variable.) I recommend that we clean this code up in dolphin.
24-07-2006