JDK-7092245 : G1: Wrong format specifier in G1PrintRegionLivenessInfo header output
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2011-09-19
  • Updated: 2013-09-18
  • Resolved: 2012-01-23
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 7 JDK 8 Other
7u2Fixed 8Fixed hs22Fixed
Description
FULL PRODUCT VERSION :


FULL OS VERSION :
any 64 bit;

Linux gremio 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:02:55 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
For printing the value of the "region-size", G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure uses SIZE_FORMAT, which is a format specifier for 64 bit values. However, the variable passed is an "int" (HeapRegion::GrainBytes), which is typically 32 bit on 64 bit platforms. This results in garbled output because the formatting function uses the full 64 bit of that memory location although only 32 bit are valid.

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run any program with -XX:+G1PrintRegionLivenessInfo -XX:+UseG1GC that causes concurrent marking. The value of "region-size" often contains a random value in that output.

EXPECTED VERSUS ACTUAL BEHAVIOR :
 -XX:+G1PrintRegionLivenessInfo -XX:+UseG1GC should result in correct output of region size information
REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
There is a bug report at https://bugs.openjdk.java.net/show_bug.cgi?id=100197 which describes a few workarounds and provides a patch:

- case the HeapRegion::GrainBytes to a size_t (least intrusive)
- add a new format specifier for printing ints
- change HeapRegion::GrainBytes to a size_t
deleted

Comments
EVALUATION See main CR
22-10-2011

EVALUATION http://hg.openjdk.java.net/hsx/hsx22/hotspot/rev/e804fc7a831e
12-10-2011

EVALUATION http://hg.openjdk.java.net/hsx/hotspot-gc/hotspot/rev/5cc33133bc6d
22-09-2011

SUGGESTED FIX Cast the value of HeapRegion::GrainBytes to a size_t in the print statement.
20-09-2011

EVALUATION The offending code is: _out->print_cr(G1PPRL_LINE_PREFIX" HEAP" G1PPRL_SUM_ADDR_FORMAT("committed") G1PPRL_SUM_ADDR_FORMAT("reserved") G1PPRL_SUM_BYTE_FORMAT("region-size"), g1_committed.start(), g1_committed.end(), g1_reserved.start(), g1_reserved.end(), HeapRegion::GrainBytes); in concurrentMark.cpp. The format specifier for region-size is: #define G1PPRL_SUM_BYTE_FORMAT(tag) " "tag": "SIZE_FORMAT Solution: _out->print_cr(G1PPRL_LINE_PREFIX" HEAP" G1PPRL_SUM_ADDR_FORMAT("committed") G1PPRL_SUM_ADDR_FORMAT("reserved") G1PPRL_SUM_BYTE_FORMAT("region-size"), g1_committed.start(), g1_committed.end(), g1_reserved.start(), g1_reserved.end(), + (size_t)HeapRegion::GrainBytes); - HeapRegion::GrainBytes); i.e. case the region size up to size_t explicitly.
19-09-2011