Skip to content

Commit 09b3b09

Browse files
coleenppull[bot]
authored andcommitted
8338064: Give better error for ConcurrentHashTable corruption
Reviewed-by: dholmes, shade
1 parent b3cfdcf commit 09b3b09

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

src/hotspot/share/utilities/concurrentHashTable.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class ConcurrentHashTable : public CHeapObj<F> {
6565
// the InternalTable or user-defined memory.
6666
class Node {
6767
private:
68+
DEBUG_ONLY(size_t _saved_hash);
6869
Node * volatile _next;
6970
VALUE _value;
7071
public:
@@ -77,6 +78,10 @@ class ConcurrentHashTable : public CHeapObj<F> {
7778
Node* next() const;
7879
void set_next(Node* node) { _next = node; }
7980
Node* const volatile * next_ptr() { return &_next; }
81+
#ifdef ASSERT
82+
size_t saved_hash() const { return _saved_hash; }
83+
void set_saved_hash(size_t hash) { _saved_hash = hash; }
84+
#endif
8085

8186
VALUE* value() { return &_value; }
8287

src/hotspot/share/utilities/concurrentHashTable.inline.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,9 @@ inline bool ConcurrentHashTable<CONFIG, F>::
679679
// Keep in odd list
680680
odd = aux->next_ptr();
681681
} else {
682-
fatal("aux_index does not match even or odd indices");
682+
const char* msg = "Cannot resize table: Node hash code has changed possibly due to corruption of the contents.";
683+
DEBUG_ONLY(fatal("%s Node hash code changed from " SIZE_FORMAT " to " SIZE_FORMAT, msg, aux->saved_hash(), aux_hash);)
684+
NOT_DEBUG(fatal("%s", msg);)
683685
}
684686
}
685687
aux = aux_next;
@@ -892,6 +894,7 @@ inline bool ConcurrentHashTable<CONFIG, F>::
892894
size_t i = 0;
893895
uintx hash = lookup_f.get_hash();
894896
Node* new_node = Node::create_node(_context, value, nullptr);
897+
DEBUG_ONLY(new_node->set_saved_hash(hash);)
895898

896899
while (true) {
897900
{
@@ -1117,6 +1120,7 @@ inline bool ConcurrentHashTable<CONFIG, F>::
11171120
Bucket* bucket = get_bucket_in(table, hash);
11181121
assert(!bucket->have_redirect() && !bucket->is_locked(), "bad");
11191122
Node* new_node = Node::create_node(_context, value, bucket->first());
1123+
DEBUG_ONLY(new_node->set_saved_hash(hash);)
11201124
if (!bucket->cas_first(new_node, bucket->first())) {
11211125
assert(false, "bad");
11221126
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8333356
27+
* @summary Verify new error message for corrupting string table contents.
28+
* @requires vm.flagless
29+
* @modules java.base/java.lang:open
30+
* @library /test/lib
31+
* @modules java.base/jdk.internal.misc
32+
* @run driver StringTableCorruptionTest test
33+
*/
34+
35+
import java.lang.reflect.Field;
36+
import java.lang.reflect.Modifier;
37+
38+
import jdk.test.lib.process.OutputAnalyzer;
39+
import jdk.test.lib.process.ProcessTools;
40+
41+
public class StringTableCorruptionTest {
42+
public static void main(String[] args) throws Exception {
43+
if (args.length > 0) {
44+
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("--add-opens", "java.base/java.lang=ALL-UNNAMED",
45+
"-XX:-CreateCoredumpOnCrash", "StringTableCorruptionTest");
46+
OutputAnalyzer output = new OutputAnalyzer(pb.start());
47+
output.shouldContain("Node hash code has changed possibly due to corruption of the contents.");
48+
output.shouldNotHaveExitValue(0);
49+
return;
50+
}
51+
52+
Field f = String.class.getDeclaredField("value");
53+
f.setAccessible(true);
54+
f.set("s1".intern(), f.get("s2"));
55+
for (int i = 0; i < 4_000_000; i++) {
56+
("s_" + i).intern();
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)