-
Bug
-
Resolution: Fixed
-
P3
-
openjdk8u262
-
b02
-
generic
-
generic
This cause wrong method/field name signature when parsing and print JFR records in dump file. This can be easily reproduced with CDS on.
Reproduce with lasted 8u build with SPECJvm2008 (tested on X86-64 )
1. java -Xshare:dump -version
2. java -Xshare:on -XX:StartFlightRecording=dumponexit,settings=profile,filename=my.jfr -jar SPECjvm2008.jar -ikv -ict crypto.signverify -wt 30s -it 30s
3. iterate JFR records and dump events, has high possiblity crash
java -cp . Parser my.jfr >tmp // check attached Parser.java
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -2
at java.lang.String.substring(String.java:1967)
at jdk.jfr.internal.tool.PrettyWriter.formatMethod(PrettyWriter.java:461)
at jdk.jfr.internal.tool.PrettyWriter.printJavaFrame(PrettyWriter.java:445)
at jdk.jfr.internal.tool.PrettyWriter.printValue(PrettyWriter.java:306)
at jdk.jfr.internal.tool.PrettyWriter.printStackTrace(PrettyWriter.java:242)
at jdk.jfr.internal.tool.PrettyWriter.print(PrettyWriter.java:221)
at jdk.jfr.consumer.RecordedObject.toString(RecordedObject.java:883)
at Parser.main(Parser.java:15)
This happens because
1. When CDS is on, it saves symbols in shared archive with their computed _identity_hash.
2. In second run, Symbols from archive and from current java process have large chances to have same identity_hash. Because symbol.identity_hash is calculated with fixed initial seed and algorithm in os::random().
3. JfrSymbolId::equals always return true when hashcode is true. So JfrSymbolId::mark(const Symbol* symbol) will return same id for different symbols.
JDK11 doesn't have this issue
1. JDK11 Symbol_identity_hash algorithm is different, it computes from _identity_hash, self address, length and first two chars.
2. When smbol has same hashcode, JfrSymbolId::on_equals return false if Symbol address is different.
Proposed fix will check if symbol is address is same in JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry* entry), this is same with JDK11.
This will not cause JFR file bigger because different symbols have same chars still have different _identity_hash. They have no chance have same hashcode in JFR symbol_id table.
Reproduce with lasted 8u build with SPECJvm2008 (tested on X86-64 )
1. java -Xshare:dump -version
2. java -Xshare:on -XX:StartFlightRecording=dumponexit,settings=profile,filename=my.jfr -jar SPECjvm2008.jar -ikv -ict crypto.signverify -wt 30s -it 30s
3. iterate JFR records and dump events, has high possiblity crash
java -cp . Parser my.jfr >tmp // check attached Parser.java
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -2
at java.lang.String.substring(String.java:1967)
at jdk.jfr.internal.tool.PrettyWriter.formatMethod(PrettyWriter.java:461)
at jdk.jfr.internal.tool.PrettyWriter.printJavaFrame(PrettyWriter.java:445)
at jdk.jfr.internal.tool.PrettyWriter.printValue(PrettyWriter.java:306)
at jdk.jfr.internal.tool.PrettyWriter.printStackTrace(PrettyWriter.java:242)
at jdk.jfr.internal.tool.PrettyWriter.print(PrettyWriter.java:221)
at jdk.jfr.consumer.RecordedObject.toString(RecordedObject.java:883)
at Parser.main(Parser.java:15)
This happens because
1. When CDS is on, it saves symbols in shared archive with their computed _identity_hash.
2. In second run, Symbols from archive and from current java process have large chances to have same identity_hash. Because symbol.identity_hash is calculated with fixed initial seed and algorithm in os::random().
3. JfrSymbolId::equals always return true when hashcode is true. So JfrSymbolId::mark(const Symbol* symbol) will return same id for different symbols.
JDK11 doesn't have this issue
1. JDK11 Symbol_identity_hash algorithm is different, it computes from _identity_hash, self address, length and first two chars.
2. When smbol has same hashcode, JfrSymbolId::on_equals return false if Symbol address is different.
Proposed fix will check if symbol is address is same in JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry* entry), this is same with JDK11.
This will not cause JFR file bigger because different symbols have same chars still have different _identity_hash. They have no chance have same hashcode in JFR symbol_id table.