Bug fix: JVM crashes when running with -Xdebug option
Shanyao Chen
shanyao.chen at linaro.org
Thu Dec 31 10:35:44 UTC 2015
hi,all:
There is a bug in jdk9 aarch32 when using jdb. And it is
described as belowing:
When running any case by the following command,
java -Xdebug
-Xrunjdwp:transport=dt_socket,address=localhost:8787,server=y,suspend=y
test
the jvm throws an error message "registers must be different: a=" r2
", b=" r0", c=" r0""
This is because in TemplateTable::jvmti_post_field_mod(Register cache,
Register index, bool is_static),there is an
assertion,assert_different_registers(cache, index, r0),and in
TemplateTable::putfield_or_static(int byte_no, bool is_static),passes
r0 as the argument index when it calls jvmti_post_field_mod. However
index and r0 should be different.
/******************code start****************/
void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
transition(vtos, vtos);
const Register cache = r2;
const Register index = r0;
...
jvmti_post_field_mod(cache, index, is_static);
/******************code end******************/
To fix this problem, it's safe to use rscratch1 as the register index
here. Then the jvm can start with -Xdebug, however,there is another
problem when using jdb.
/****command start****/
$ jdb -attach 127.0.0.1:8787
$ stop in test.main
$ run
/*****command end*****/
Everything is ok until here, the test case stop in main correctly.
However, if you send "next" or "continue" from the breakpoint,then the
jvm will crash by SIGSEGV in TemplateTable::_breakpoint()
/******************code start****************/
void TemplateTable::_breakpoint() {
...
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
InterpreterRuntime::get_original_bytecode_at),
c_rarg1, rbcp);
__ mov(r3, r0);
// post the breakpoint event
__ call_VM(noreg,
CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint),
rmethod, rbcp);
// complete the execution of original bytecode
__ mov(rscratch1, r3);
__ dispatch_only_normal(vtos);
}
/******************code end******************/
After getting the unpatched byte code, r0 is saved to r3 by __ mov(r3,
r0), and is restored to rscratch1 before dispatching. However, r3 was
destroyed by InterpreterRuntime::_breakpoint. In aarch64,the value of
r0 is saved to x19, This is safe because that x19 is a callee-saved
register. In aarch32, there is no free callee-saved register can be
used like x19,then we save r0 to stack here.
Bug Patch:
/******************patch start****************/
diff -r f69a4ff3f0bb src/cpu/aarch32/vm/templateTable_aarch32.cpp
--- a/src/cpu/aarch32/vm/templateTable_aarch32.cpp Wed Dec 23
12:21:32 2015 +0000
+++ b/src/cpu/aarch32/vm/templateTable_aarch32.cpp Thu Dec 31
17:10:31 2015 +0800
@@ -2721,7 +2721,7 @@
void TemplateTable::putfield_or_static(int byte_no, bool is_static,
RewriteControl rc) {
transition(vtos, vtos);
const Register cache = r2;
- const Register index = r0;
+ const Register index = rscratch1;
const Register obj = r2;
const Register off = rscratch2;
const Register flags = r14;
@@ -3752,7 +3752,7 @@
CAST_FROM_FN_PTR(address,
InterpreterRuntime::get_original_bytecode_at),
c_rarg1, rbcp);
- __ mov(r3, r0);
+ __ push(r0);
// post the breakpoint event
__ call_VM(noreg,
@@ -3760,7 +3760,7 @@
rmethod, rbcp);
// complete the execution of original bytecode
- __ mov(rscratch1, r3);
+ __ pop(rscratch1);
__ dispatch_only_normal(vtos);
}
/******************patch end******************/
best regards,
Shanyao Chen
-------------- next part --------------
diff -r f69a4ff3f0bb src/cpu/aarch32/vm/templateTable_aarch32.cpp
--- a/src/cpu/aarch32/vm/templateTable_aarch32.cpp Wed Dec 23 12:21:32 2015 +0000
+++ b/src/cpu/aarch32/vm/templateTable_aarch32.cpp Thu Dec 31 17:10:31 2015 +0800
@@ -2721,7 +2721,7 @@
void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
transition(vtos, vtos);
const Register cache = r2;
- const Register index = r0;
+ const Register index = rscratch1;
const Register obj = r2;
const Register off = rscratch2;
const Register flags = r14;
@@ -3752,7 +3752,7 @@
CAST_FROM_FN_PTR(address,
InterpreterRuntime::get_original_bytecode_at),
c_rarg1, rbcp);
- __ mov(r3, r0);
+ __ push(r0);
// post the breakpoint event
__ call_VM(noreg,
@@ -3760,7 +3760,7 @@
rmethod, rbcp);
// complete the execution of original bytecode
- __ mov(rscratch1, r3);
+ __ pop(rscratch1);
__ dispatch_only_normal(vtos);
}
More information about the aarch32-port-dev
mailing list