Skip to content

Commit 1eee15e

Browse files
mhaessigSendaoYan
authored andcommitted
8258229: Crash in nmethod::reloc_string_for
Reviewed-by: galder, thartmann
1 parent 8c4f2ff commit 1eee15e

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

src/hotspot/share/code/nmethod.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "code/dependencies.hpp"
2929
#include "code/nativeInst.hpp"
3030
#include "code/nmethod.inline.hpp"
31+
#include "code/relocInfo.hpp"
3132
#include "code/scopeDesc.hpp"
3233
#include "compiler/abstractCompiler.hpp"
3334
#include "compiler/compilationLog.hpp"
@@ -1648,6 +1649,10 @@ void nmethod::maybe_print_nmethod(const DirectiveSet* directive) {
16481649
}
16491650

16501651
void nmethod::print_nmethod(bool printmethod) {
1652+
// Enter a critical section to prevent a race with deopts that patch code and updates the relocation info.
1653+
// Unfortunately, we have to lock the NMethodState_lock before the tty lock due to the deadlock rules and
1654+
// cannot lock in a more finely grained manner.
1655+
ConditionalMutexLocker ml(NMethodState_lock, !NMethodState_lock->owned_by_self(), Mutex::_no_safepoint_check_flag);
16511656
ttyLocker ttyl; // keep the following output all in one block
16521657
if (xtty != nullptr) {
16531658
xtty->begin_head("print_nmethod");
@@ -2037,6 +2042,17 @@ bool nmethod::make_not_entrant(const char* reason) {
20372042
// cache call.
20382043
NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
20392044
SharedRuntime::get_handle_wrong_method_stub());
2045+
2046+
// Update the relocation info for the patched entry.
2047+
// First, get the old relocation info...
2048+
RelocIterator iter(this, verified_entry_point(), verified_entry_point() + 8);
2049+
if (iter.next() && iter.addr() == verified_entry_point()) {
2050+
Relocation* old_reloc = iter.reloc();
2051+
// ...then reset the iterator to update it.
2052+
RelocIterator iter(this, verified_entry_point(), verified_entry_point() + 8);
2053+
relocInfo::change_reloc_info_for_address(&iter, verified_entry_point(), old_reloc->type(),
2054+
relocInfo::relocType::runtime_call_type);
2055+
}
20402056
}
20412057

20422058
if (update_recompile_counts()) {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (c) 2025, 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 8258229
27+
* @summary If a method is made not entrant while printing the assembly, hotspot crashes due to mismatched relocation information.
28+
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:-TieredCompilation -XX:+DeoptimizeALot -XX:CompileCommand=print,java/math/BitSieve.bit
29+
* compiler.print.TestPrintAssemblyDeoptRace
30+
*/
31+
32+
package compiler.print;
33+
34+
import java.util.Arrays;
35+
36+
import java.security.Security;
37+
import java.security.Provider;
38+
import java.security.KeyPair;
39+
import java.security.KeyPairGenerator;
40+
import java.security.interfaces.RSAPrivateKey;
41+
import java.security.interfaces.RSAPublicKey;
42+
import java.security.spec.MGF1ParameterSpec;
43+
44+
import javax.crypto.Cipher;
45+
import javax.crypto.spec.OAEPParameterSpec;
46+
import javax.crypto.spec.PSource;
47+
48+
public class TestPrintAssemblyDeoptRace {
49+
private static RSAPrivateKey privateKey;
50+
private static RSAPublicKey publicKey;
51+
static Provider cp;
52+
53+
public static void main(String args[]) throws Exception {
54+
cp = Security.getProvider("SunJCE");
55+
System.out.println("Testing provider " + cp.getName() + "...");
56+
Provider kfp = Security.getProvider("SunRsaSign");
57+
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", kfp);
58+
kpg.initialize(2048);
59+
KeyPair kp = kpg.generateKeyPair();
60+
privateKey = (RSAPrivateKey) kp.getPrivate();
61+
publicKey = (RSAPublicKey) kp.getPublic();
62+
testEncryptDecrypt(new OAEPParameterSpec("SHA-512/256", "MGF1",
63+
MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT), 190);
64+
65+
}
66+
67+
private static void testEncryptDecrypt(OAEPParameterSpec spec,
68+
int dataLength) throws Exception {
69+
70+
Cipher c = Cipher.getInstance("RSA/ECB/OAEPPadding", cp);
71+
c.init(Cipher.ENCRYPT_MODE, publicKey, spec);
72+
73+
byte[] data = new byte[dataLength];
74+
byte[] enc = c.doFinal(data);
75+
c.init(Cipher.DECRYPT_MODE, privateKey, spec);
76+
}
77+
}

0 commit comments

Comments
 (0)