United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-7092245 : G1: Wrong format specifier in G1PrintRegionLivenessInfo header output

Details
Type:
Bug
Submit Date:
2011-09-19
Status:
Closed
Updated Date:
2012-12-05
Project Name:
JDK
Resolved Date:
2012-01-23
Component:
hotspot
OS:
linux
Sub-Component:
gc
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs23 (b02)

Related Reports
Backport:
Backport:
Backport:
Backport:

Sub Tasks

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
                                     
2011-10-22
EVALUATION

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

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

Cast the value of HeapRegion::GrainBytes to a size_t in the print statement.
                                     
2011-09-20
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.
                                     
2011-09-19



Hardware and Software, Engineered to Work Together