Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
98af3e8e
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
98af3e8e
编写于
4月 09, 2012
作者:
D
dcubed
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
078dc371
c9d63d8e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
658 addition
and
67 deletion
+658
-67
src/cpu/x86/vm/templateTable_x86_32.cpp
src/cpu/x86/vm/templateTable_x86_32.cpp
+43
-50
src/cpu/x86/vm/templateTable_x86_64.cpp
src/cpu/x86/vm/templateTable_x86_64.cpp
+23
-17
test/runtime/7158988/FieldMonitor.java
test/runtime/7158988/FieldMonitor.java
+249
-0
test/runtime/7158988/TestFieldMonitor.sh
test/runtime/7158988/TestFieldMonitor.sh
+94
-0
test/runtime/7158988/TestPostFieldModification.java
test/runtime/7158988/TestPostFieldModification.java
+249
-0
未找到文件。
src/cpu/x86/vm/templateTable_x86_32.cpp
浏览文件 @
98af3e8e
...
@@ -2651,56 +2651,49 @@ void TemplateTable::jvmti_post_fast_field_mod() {
...
@@ -2651,56 +2651,49 @@ void TemplateTable::jvmti_post_fast_field_mod() {
// Check to see if a field modification watch has been set before we take
// Check to see if a field modification watch has been set before we take
// the time to call into the VM.
// the time to call into the VM.
Label
L2
;
Label
L2
;
__
mov32
(
rcx
,
ExternalAddress
((
address
)
JvmtiExport
::
get_field_modification_count_addr
()));
__
mov32
(
rcx
,
ExternalAddress
((
address
)
JvmtiExport
::
get_field_modification_count_addr
()));
__
testl
(
rcx
,
rcx
);
__
testl
(
rcx
,
rcx
);
__
jcc
(
Assembler
::
zero
,
L2
);
__
jcc
(
Assembler
::
zero
,
L2
);
__
pop_ptr
(
rbx
);
// copy the object pointer from tos
__
pop_ptr
(
rbx
);
// copy the object pointer from tos
__
verify_oop
(
rbx
);
__
verify_oop
(
rbx
);
__
push_ptr
(
rbx
);
// put the object pointer back on tos
__
push_ptr
(
rbx
);
// put the object pointer back on tos
__
subptr
(
rsp
,
sizeof
(
jvalue
));
// add space for a jvalue object
__
mov
(
rcx
,
rsp
);
// Save tos values before call_VM() clobbers them. Since we have
__
push_ptr
(
rbx
);
// save object pointer so we can steal rbx,
// to do it for every data type, we use the saved values as the
__
xorptr
(
rbx
,
rbx
);
// jvalue object.
const
Address
lo_value
(
rcx
,
rbx
,
Address
::
times_1
,
0
*
wordSize
);
switch
(
bytecode
())
{
// load values into the jvalue object
const
Address
hi_value
(
rcx
,
rbx
,
Address
::
times_1
,
1
*
wordSize
);
case
Bytecodes
::
_fast_aputfield
:
__
push_ptr
(
rax
);
break
;
switch
(
bytecode
())
{
// load values into the jvalue object
case
Bytecodes
::
_fast_bputfield
:
// fall through
case
Bytecodes
::
_fast_bputfield
:
__
movb
(
lo_value
,
rax
);
break
;
case
Bytecodes
::
_fast_sputfield
:
// fall through
case
Bytecodes
::
_fast_sputfield
:
__
movw
(
lo_value
,
rax
);
break
;
case
Bytecodes
::
_fast_cputfield
:
// fall through
case
Bytecodes
::
_fast_cputfield
:
__
movw
(
lo_value
,
rax
);
break
;
case
Bytecodes
::
_fast_iputfield
:
__
push_i
(
rax
);
break
;
case
Bytecodes
::
_fast_iputfield
:
__
movl
(
lo_value
,
rax
);
break
;
case
Bytecodes
::
_fast_dputfield
:
__
push_d
();
break
;
case
Bytecodes
::
_fast_lputfield
:
case
Bytecodes
::
_fast_fputfield
:
__
push_f
();
break
;
NOT_LP64
(
__
movptr
(
hi_value
,
rdx
));
case
Bytecodes
::
_fast_lputfield
:
__
push_l
(
rax
);
break
;
__
movptr
(
lo_value
,
rax
);
break
;
default:
ShouldNotReachHere
();
// need to call fld_s() after fstp_s() to restore the value for below
}
case
Bytecodes
::
_fast_fputfield
:
__
fstp_s
(
lo_value
);
__
fld_s
(
lo_value
);
break
;
__
mov
(
rcx
,
rsp
);
// points to jvalue on the stack
// access constant pool cache entry
// need to call fld_d() after fstp_d() to restore the value for below
__
get_cache_entry_pointer_at_bcp
(
rax
,
rdx
,
1
);
case
Bytecodes
::
_fast_dputfield
:
__
fstp_d
(
lo_value
);
__
fld_d
(
lo_value
);
break
;
__
verify_oop
(
rbx
);
// rbx,: object pointer copied above
// since rcx is not an object we don't call store_check() here
// rax,: cache entry pointer
case
Bytecodes
::
_fast_aputfield
:
__
movptr
(
lo_value
,
rax
);
break
;
// rcx: jvalue object on the stack
__
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
post_field_modification
),
rbx
,
rax
,
rcx
);
default:
ShouldNotReachHere
();
}
switch
(
bytecode
())
{
// restore tos values
__
pop_ptr
(
rbx
);
// restore copy of object pointer
case
Bytecodes
::
_fast_aputfield
:
__
pop_ptr
(
rax
);
break
;
case
Bytecodes
::
_fast_bputfield
:
// fall through
// Save rax, and sometimes rdx because call_VM() will clobber them,
case
Bytecodes
::
_fast_sputfield
:
// fall through
// then use them for JVM/DI purposes
case
Bytecodes
::
_fast_cputfield
:
// fall through
__
push
(
rax
);
case
Bytecodes
::
_fast_iputfield
:
__
pop_i
(
rax
);
break
;
if
(
bytecode
()
==
Bytecodes
::
_fast_lputfield
)
__
push
(
rdx
);
case
Bytecodes
::
_fast_dputfield
:
__
pop_d
();
break
;
// access constant pool cache entry
case
Bytecodes
::
_fast_fputfield
:
__
pop_f
();
break
;
__
get_cache_entry_pointer_at_bcp
(
rax
,
rdx
,
1
);
case
Bytecodes
::
_fast_lputfield
:
__
pop_l
(
rax
);
break
;
__
verify_oop
(
rbx
);
}
// rbx,: object pointer copied above
__
bind
(
L2
);
// rax,: cache entry pointer
// rcx: jvalue object on the stack
__
call_VM
(
noreg
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
post_field_modification
),
rbx
,
rax
,
rcx
);
if
(
bytecode
()
==
Bytecodes
::
_fast_lputfield
)
__
pop
(
rdx
);
// restore high value
__
pop
(
rax
);
// restore lower value
__
addptr
(
rsp
,
sizeof
(
jvalue
));
// release jvalue object space
__
bind
(
L2
);
}
}
}
}
...
...
src/cpu/x86/vm/templateTable_x86_64.cpp
浏览文件 @
98af3e8e
...
@@ -2685,26 +2685,23 @@ void TemplateTable::jvmti_post_fast_field_mod() {
...
@@ -2685,26 +2685,23 @@ void TemplateTable::jvmti_post_fast_field_mod() {
__
pop_ptr
(
rbx
);
// copy the object pointer from tos
__
pop_ptr
(
rbx
);
// copy the object pointer from tos
__
verify_oop
(
rbx
);
__
verify_oop
(
rbx
);
__
push_ptr
(
rbx
);
// put the object pointer back on tos
__
push_ptr
(
rbx
);
// put the object pointer back on tos
__
subptr
(
rsp
,
sizeof
(
jvalue
));
// add space for a jvalue object
// Save tos values before call_VM() clobbers them. Since we have
__
mov
(
c_rarg3
,
rsp
);
// to do it for every data type, we use the saved values as the
const
Address
field
(
c_rarg3
,
0
);
// jvalue object.
switch
(
bytecode
())
{
// load values into the jvalue object
switch
(
bytecode
())
{
// load values into the jvalue object
case
Bytecodes
::
_fast_aputfield
:
__
movq
(
field
,
rax
);
break
;
case
Bytecodes
::
_fast_aputfield
:
__
push_ptr
(
rax
);
break
;
case
Bytecodes
::
_fast_lputfield
:
__
movq
(
field
,
rax
);
break
;
case
Bytecodes
::
_fast_bputfield
:
// fall through
case
Bytecodes
::
_fast_iputfield
:
__
movl
(
field
,
rax
);
break
;
case
Bytecodes
::
_fast_bputfield
:
__
movb
(
field
,
rax
);
break
;
case
Bytecodes
::
_fast_sputfield
:
// fall through
case
Bytecodes
::
_fast_sputfield
:
// fall through
case
Bytecodes
::
_fast_cputfield
:
__
movw
(
field
,
rax
);
break
;
case
Bytecodes
::
_fast_cputfield
:
// fall through
case
Bytecodes
::
_fast_fputfield
:
__
movflt
(
field
,
xmm0
);
break
;
case
Bytecodes
::
_fast_iputfield
:
__
push_i
(
rax
);
break
;
case
Bytecodes
::
_fast_dputfield
:
__
movdbl
(
field
,
xmm0
);
break
;
case
Bytecodes
::
_fast_dputfield
:
__
push_d
();
break
;
case
Bytecodes
::
_fast_fputfield
:
__
push_f
();
break
;
case
Bytecodes
::
_fast_lputfield
:
__
push_l
(
rax
);
break
;
default:
default:
ShouldNotReachHere
();
ShouldNotReachHere
();
}
}
__
mov
(
c_rarg3
,
rsp
);
// points to jvalue on the stack
// Save rax because call_VM() will clobber it, then use it for
// JVMTI purposes
__
push
(
rax
);
// access constant pool cache entry
// access constant pool cache entry
__
get_cache_entry_pointer_at_bcp
(
c_rarg2
,
rax
,
1
);
__
get_cache_entry_pointer_at_bcp
(
c_rarg2
,
rax
,
1
);
__
verify_oop
(
rbx
);
__
verify_oop
(
rbx
);
...
@@ -2715,8 +2712,17 @@ void TemplateTable::jvmti_post_fast_field_mod() {
...
@@ -2715,8 +2712,17 @@ void TemplateTable::jvmti_post_fast_field_mod() {
CAST_FROM_FN_PTR
(
address
,
CAST_FROM_FN_PTR
(
address
,
InterpreterRuntime
::
post_field_modification
),
InterpreterRuntime
::
post_field_modification
),
rbx
,
c_rarg2
,
c_rarg3
);
rbx
,
c_rarg2
,
c_rarg3
);
__
pop
(
rax
);
// restore lower value
__
addptr
(
rsp
,
sizeof
(
jvalue
));
// release jvalue object space
switch
(
bytecode
())
{
// restore tos values
case
Bytecodes
::
_fast_aputfield
:
__
pop_ptr
(
rax
);
break
;
case
Bytecodes
::
_fast_bputfield
:
// fall through
case
Bytecodes
::
_fast_sputfield
:
// fall through
case
Bytecodes
::
_fast_cputfield
:
// fall through
case
Bytecodes
::
_fast_iputfield
:
__
pop_i
(
rax
);
break
;
case
Bytecodes
::
_fast_dputfield
:
__
pop_d
();
break
;
case
Bytecodes
::
_fast_fputfield
:
__
pop_f
();
break
;
case
Bytecodes
::
_fast_lputfield
:
__
pop_l
(
rax
);
break
;
}
__
bind
(
L2
);
__
bind
(
L2
);
}
}
}
}
...
...
test/runtime/7158988/FieldMonitor.java
0 → 100644
浏览文件 @
98af3e8e
/*
* Copyright 2012 SAP AG. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test FieldMonitor.java
* @bug 7158988
* @summary verify jvm does not crash while debugging
* @run shell TestFieldMonitor.sh
* @author axel.siebenborn@sap.com
*/
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.OutputStream
;
import
java.io.OutputStreamWriter
;
import
java.io.Reader
;
import
java.io.Writer
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
com.sun.jdi.Bootstrap
;
import
com.sun.jdi.Field
;
import
com.sun.jdi.ReferenceType
;
import
com.sun.jdi.VirtualMachine
;
import
com.sun.jdi.connect.Connector
;
import
com.sun.jdi.connect.IllegalConnectorArgumentsException
;
import
com.sun.jdi.connect.LaunchingConnector
;
import
com.sun.jdi.connect.VMStartException
;
import
com.sun.jdi.event.ClassPrepareEvent
;
import
com.sun.jdi.event.Event
;
import
com.sun.jdi.event.EventQueue
;
import
com.sun.jdi.event.EventSet
;
import
com.sun.jdi.event.ModificationWatchpointEvent
;
import
com.sun.jdi.event.VMDeathEvent
;
import
com.sun.jdi.event.VMDisconnectEvent
;
import
com.sun.jdi.request.ClassPrepareRequest
;
import
com.sun.jdi.request.EventRequest
;
import
com.sun.jdi.request.EventRequestManager
;
import
com.sun.jdi.request.ModificationWatchpointRequest
;
public
class
FieldMonitor
{
public
static
final
String
CLASS_NAME
=
"TestPostFieldModification"
;
public
static
final
String
FIELD_NAME
=
"value"
;
public
static
final
String
ARGUMENTS
=
"-Xshare:off -XX:+PrintGC"
;
public
static
void
main
(
String
[]
args
)
throws
IOException
,
InterruptedException
{
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
sb
.
append
(
' '
);
sb
.
append
(
args
[
i
]);
}
//VirtualMachine vm = launchTarget(sb.toString());
VirtualMachine
vm
=
launchTarget
(
CLASS_NAME
);
System
.
out
.
println
(
"Vm launched"
);
// set watch field on already loaded classes
List
<
ReferenceType
>
referenceTypes
=
vm
.
classesByName
(
CLASS_NAME
);
for
(
ReferenceType
refType
:
referenceTypes
)
{
addFieldWatch
(
vm
,
refType
);
}
// watch for loaded classes
addClassWatch
(
vm
);
// process events
EventQueue
eventQueue
=
vm
.
eventQueue
();
// resume the vm
Process
process
=
vm
.
process
();
// Copy target's output and error to our output and error.
Thread
outThread
=
new
StreamRedirectThread
(
"out reader"
,
process
.
getInputStream
());
Thread
errThread
=
new
StreamRedirectThread
(
"error reader"
,
process
.
getErrorStream
());
errThread
.
start
();
outThread
.
start
();
vm
.
resume
();
boolean
connected
=
true
;
while
(
connected
)
{
EventSet
eventSet
=
eventQueue
.
remove
();
for
(
Event
event
:
eventSet
)
{
if
(
event
instanceof
VMDeathEvent
||
event
instanceof
VMDisconnectEvent
)
{
// exit
connected
=
false
;
}
else
if
(
event
instanceof
ClassPrepareEvent
)
{
// watch field on loaded class
System
.
out
.
println
(
"ClassPrepareEvent"
);
ClassPrepareEvent
classPrepEvent
=
(
ClassPrepareEvent
)
event
;
ReferenceType
refType
=
classPrepEvent
.
referenceType
();
addFieldWatch
(
vm
,
refType
);
}
else
if
(
event
instanceof
ModificationWatchpointEvent
)
{
System
.
out
.
println
(
"sleep for 500 ms"
);
Thread
.
sleep
(
500
);
System
.
out
.
println
(
"resume..."
);
ModificationWatchpointEvent
modEvent
=
(
ModificationWatchpointEvent
)
event
;
System
.
out
.
println
(
"old="
+
modEvent
.
valueCurrent
());
System
.
out
.
println
(
"new="
+
modEvent
.
valueToBe
());
System
.
out
.
println
();
}
}
eventSet
.
resume
();
}
// Shutdown begins when event thread terminates
try
{
errThread
.
join
();
// Make sure output is forwarded
outThread
.
join
();
}
catch
(
InterruptedException
exc
)
{
// we don't interrupt
}
}
/**
* Find a com.sun.jdi.CommandLineLaunch connector
*/
static
LaunchingConnector
findLaunchingConnector
()
{
List
<
Connector
>
connectors
=
Bootstrap
.
virtualMachineManager
().
allConnectors
();
Iterator
<
Connector
>
iter
=
connectors
.
iterator
();
while
(
iter
.
hasNext
())
{
Connector
connector
=
iter
.
next
();
if
(
connector
.
name
().
equals
(
"com.sun.jdi.CommandLineLaunch"
))
{
return
(
LaunchingConnector
)
connector
;
}
}
throw
new
Error
(
"No launching connector"
);
}
/**
* Return the launching connector's arguments.
*/
static
Map
<
String
,
Connector
.
Argument
>
connectorArguments
(
LaunchingConnector
connector
,
String
mainArgs
)
{
Map
<
String
,
Connector
.
Argument
>
arguments
=
connector
.
defaultArguments
();
for
(
String
key
:
arguments
.
keySet
())
{
System
.
out
.
println
(
key
);
}
Connector
.
Argument
mainArg
=
(
Connector
.
Argument
)
arguments
.
get
(
"main"
);
if
(
mainArg
==
null
)
{
throw
new
Error
(
"Bad launching connector"
);
}
mainArg
.
setValue
(
mainArgs
);
Connector
.
Argument
optionsArg
=
(
Connector
.
Argument
)
arguments
.
get
(
"options"
);
if
(
optionsArg
==
null
)
{
throw
new
Error
(
"Bad launching connector"
);
}
optionsArg
.
setValue
(
ARGUMENTS
);
return
arguments
;
}
static
VirtualMachine
launchTarget
(
String
mainArgs
)
{
LaunchingConnector
connector
=
findLaunchingConnector
();
Map
arguments
=
connectorArguments
(
connector
,
mainArgs
);
try
{
return
(
VirtualMachine
)
connector
.
launch
(
arguments
);
}
catch
(
IOException
exc
)
{
throw
new
Error
(
"Unable to launch target VM: "
+
exc
);
}
catch
(
IllegalConnectorArgumentsException
exc
)
{
throw
new
Error
(
"Internal error: "
+
exc
);
}
catch
(
VMStartException
exc
)
{
throw
new
Error
(
"Target VM failed to initialize: "
+
exc
.
getMessage
());
}
}
private
static
void
addClassWatch
(
VirtualMachine
vm
)
{
EventRequestManager
erm
=
vm
.
eventRequestManager
();
ClassPrepareRequest
classPrepareRequest
=
erm
.
createClassPrepareRequest
();
classPrepareRequest
.
addClassFilter
(
CLASS_NAME
);
classPrepareRequest
.
setEnabled
(
true
);
}
private
static
void
addFieldWatch
(
VirtualMachine
vm
,
ReferenceType
refType
)
{
EventRequestManager
erm
=
vm
.
eventRequestManager
();
Field
field
=
refType
.
fieldByName
(
FIELD_NAME
);
ModificationWatchpointRequest
modificationWatchpointRequest
=
erm
.
createModificationWatchpointRequest
(
field
);
modificationWatchpointRequest
.
setSuspendPolicy
(
EventRequest
.
SUSPEND_EVENT_THREAD
);
modificationWatchpointRequest
.
setEnabled
(
true
);
}
}
class
StreamRedirectThread
extends
Thread
{
private
final
BufferedReader
in
;
private
static
final
int
BUFFER_SIZE
=
2048
;
/**
* Set up for copy.
* @param name Name of the thread
* @param in Stream to copy from
* @param out Stream to copy to
*/
StreamRedirectThread
(
String
name
,
InputStream
in
)
{
super
(
name
);
this
.
in
=
new
BufferedReader
(
new
InputStreamReader
(
in
));
}
/**
* Copy.
*/
public
void
run
()
{
try
{
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
System
.
out
.
println
(
"testvm: "
+
line
);
}
System
.
out
.
flush
();
}
catch
(
IOException
exc
)
{
System
.
err
.
println
(
"Child I/O Transfer - "
+
exc
);
}
}
}
test/runtime/7158988/TestFieldMonitor.sh
0 → 100644
浏览文件 @
98af3e8e
#!/bin/sh
if
[
"
${
TESTSRC
}
"
=
""
]
then
TESTSRC
=
.
fi
if
[
"
${
TESTJAVA
}
"
=
""
]
then
PARENT
=
`
dirname
\`
which java
\`
`
TESTJAVA
=
`
dirname
${
PARENT
}
`
echo
"TESTJAVA not set, selecting "
${
TESTJAVA
}
echo
"If this is incorrect, try setting the variable manually."
fi
if
[
"
${
TESTCLASSES
}
"
=
""
]
then
echo
"TESTCLASSES not set. Test cannot execute. Failed."
exit
1
fi
BIT_FLAG
=
""
# set platform-dependent variables
OS
=
`
uname
-s
`
case
"
$OS
"
in
SunOS
|
Linux
)
NULL
=
/dev/null
PS
=
":"
FS
=
"/"
## for solaris, linux it's HOME
FILE_LOCATION
=
$HOME
if
[
-f
${
FILE_LOCATION
}${
FS
}
JDK64BIT
-a
${
OS
}
=
"SunOS"
-a
`
uname
-p
`
=
'sparc'
]
then
BIT_FLAG
=
"-d64"
fi
;;
Windows_95
|
Windows_98
|
Windows_ME
)
NULL
=
NUL
PS
=
";"
FS
=
"
\\
"
echo
"Test skipped, only for WinNT"
exit
0
;;
Windows_NT
)
NULL
=
NUL
PS
=
";"
FS
=
"
\\
"
;;
*
)
echo
"Unrecognized system!"
exit
1
;
;;
esac
#CLASSPATH=.${PS}${TESTCLASSES} ; export CLASSPATH
cp
${
TESTSRC
}${
FS
}*
.java
.
${
TESTJAVA
}${
FS
}
bin
${
FS
}
java
${
BIT_FLAG
}
-fullversion
${
TESTJAVA
}${
FS
}
bin
${
FS
}
javac
-classpath
.
${
PS
}
$TESTJAVA
${
FS
}
lib
${
FS
}
tools.jar
*
.java
${
TESTJAVA
}${
FS
}
bin
${
FS
}
java
${
BIT_FLAG
}
-classpath
.
${
PS
}
$TESTJAVA
${
FS
}
lib
${
FS
}
tools.jar FieldMonitor
>
test.out 2>&1 &
P_PID
=
$!
sleep
60
STATUS
=
0
case
"
$OS
"
in
SunOS
|
Linux
)
ps
-ef
|
grep
$P_PID
|
grep
-v
grep
>
${
NULL
}
if
[
$?
=
0
]
;
then
kill
-9
$P_PID
STATUS
=
1
fi
;;
*
)
ps |
grep
-i
"FieldMonitor"
|
grep
-v
grep
>
${
NULL
}
if
[
$?
=
0
]
;
then
C_PID
=
`
ps |
grep
-i
"FieldMonitor"
|
awk
'{print $1}'
`
kill
-s
9
$C_PID
STATUS
=
1
fi
;;
esac
grep
"A fatal error has been detected"
test.out
>
${
NULL
}
if
[
$?
=
0
]
;
then
cat
test.out
STATUS
=
1
fi
exit
$STATUS
test/runtime/7158988/TestPostFieldModification.java
0 → 100644
浏览文件 @
98af3e8e
/*
* Copyright 2012 SAP AG. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test FieldMonitor.java
* @bug 7158988
* @summary verify jvm does not crash while debugging
* @run shell TestFieldMonitor.sh
* @author axel.siebenborn@sap.com
*/
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.OutputStream
;
import
java.io.OutputStreamWriter
;
import
java.io.Reader
;
import
java.io.Writer
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
com.sun.jdi.Bootstrap
;
import
com.sun.jdi.Field
;
import
com.sun.jdi.ReferenceType
;
import
com.sun.jdi.VirtualMachine
;
import
com.sun.jdi.connect.Connector
;
import
com.sun.jdi.connect.IllegalConnectorArgumentsException
;
import
com.sun.jdi.connect.LaunchingConnector
;
import
com.sun.jdi.connect.VMStartException
;
import
com.sun.jdi.event.ClassPrepareEvent
;
import
com.sun.jdi.event.Event
;
import
com.sun.jdi.event.EventQueue
;
import
com.sun.jdi.event.EventSet
;
import
com.sun.jdi.event.ModificationWatchpointEvent
;
import
com.sun.jdi.event.VMDeathEvent
;
import
com.sun.jdi.event.VMDisconnectEvent
;
import
com.sun.jdi.request.ClassPrepareRequest
;
import
com.sun.jdi.request.EventRequest
;
import
com.sun.jdi.request.EventRequestManager
;
import
com.sun.jdi.request.ModificationWatchpointRequest
;
public
class
FieldMonitor
{
public
static
final
String
CLASS_NAME
=
"TestPostFieldModification"
;
public
static
final
String
FIELD_NAME
=
"value"
;
public
static
final
String
ARGUMENTS
=
"-Xshare:off -XX:+PrintGC"
;
public
static
void
main
(
String
[]
args
)
throws
IOException
,
InterruptedException
{
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
sb
.
append
(
' '
);
sb
.
append
(
args
[
i
]);
}
//VirtualMachine vm = launchTarget(sb.toString());
VirtualMachine
vm
=
launchTarget
(
CLASS_NAME
);
System
.
out
.
println
(
"Vm launched"
);
// set watch field on already loaded classes
List
<
ReferenceType
>
referenceTypes
=
vm
.
classesByName
(
CLASS_NAME
);
for
(
ReferenceType
refType
:
referenceTypes
)
{
addFieldWatch
(
vm
,
refType
);
}
// watch for loaded classes
addClassWatch
(
vm
);
// process events
EventQueue
eventQueue
=
vm
.
eventQueue
();
// resume the vm
Process
process
=
vm
.
process
();
// Copy target's output and error to our output and error.
Thread
outThread
=
new
StreamRedirectThread
(
"out reader"
,
process
.
getInputStream
());
Thread
errThread
=
new
StreamRedirectThread
(
"error reader"
,
process
.
getErrorStream
());
errThread
.
start
();
outThread
.
start
();
vm
.
resume
();
boolean
connected
=
true
;
while
(
connected
)
{
EventSet
eventSet
=
eventQueue
.
remove
();
for
(
Event
event
:
eventSet
)
{
if
(
event
instanceof
VMDeathEvent
||
event
instanceof
VMDisconnectEvent
)
{
// exit
connected
=
false
;
}
else
if
(
event
instanceof
ClassPrepareEvent
)
{
// watch field on loaded class
System
.
out
.
println
(
"ClassPrepareEvent"
);
ClassPrepareEvent
classPrepEvent
=
(
ClassPrepareEvent
)
event
;
ReferenceType
refType
=
classPrepEvent
.
referenceType
();
addFieldWatch
(
vm
,
refType
);
}
else
if
(
event
instanceof
ModificationWatchpointEvent
)
{
System
.
out
.
println
(
"sleep for 500 ms"
);
Thread
.
sleep
(
500
);
System
.
out
.
println
(
"resume..."
);
ModificationWatchpointEvent
modEvent
=
(
ModificationWatchpointEvent
)
event
;
System
.
out
.
println
(
"old="
+
modEvent
.
valueCurrent
());
System
.
out
.
println
(
"new="
+
modEvent
.
valueToBe
());
System
.
out
.
println
();
}
}
eventSet
.
resume
();
}
// Shutdown begins when event thread terminates
try
{
errThread
.
join
();
// Make sure output is forwarded
outThread
.
join
();
}
catch
(
InterruptedException
exc
)
{
// we don't interrupt
}
}
/**
* Find a com.sun.jdi.CommandLineLaunch connector
*/
static
LaunchingConnector
findLaunchingConnector
()
{
List
<
Connector
>
connectors
=
Bootstrap
.
virtualMachineManager
().
allConnectors
();
Iterator
<
Connector
>
iter
=
connectors
.
iterator
();
while
(
iter
.
hasNext
())
{
Connector
connector
=
iter
.
next
();
if
(
connector
.
name
().
equals
(
"com.sun.jdi.CommandLineLaunch"
))
{
return
(
LaunchingConnector
)
connector
;
}
}
throw
new
Error
(
"No launching connector"
);
}
/**
* Return the launching connector's arguments.
*/
static
Map
<
String
,
Connector
.
Argument
>
connectorArguments
(
LaunchingConnector
connector
,
String
mainArgs
)
{
Map
<
String
,
Connector
.
Argument
>
arguments
=
connector
.
defaultArguments
();
for
(
String
key
:
arguments
.
keySet
())
{
System
.
out
.
println
(
key
);
}
Connector
.
Argument
mainArg
=
(
Connector
.
Argument
)
arguments
.
get
(
"main"
);
if
(
mainArg
==
null
)
{
throw
new
Error
(
"Bad launching connector"
);
}
mainArg
.
setValue
(
mainArgs
);
Connector
.
Argument
optionsArg
=
(
Connector
.
Argument
)
arguments
.
get
(
"options"
);
if
(
optionsArg
==
null
)
{
throw
new
Error
(
"Bad launching connector"
);
}
optionsArg
.
setValue
(
ARGUMENTS
);
return
arguments
;
}
static
VirtualMachine
launchTarget
(
String
mainArgs
)
{
LaunchingConnector
connector
=
findLaunchingConnector
();
Map
arguments
=
connectorArguments
(
connector
,
mainArgs
);
try
{
return
(
VirtualMachine
)
connector
.
launch
(
arguments
);
}
catch
(
IOException
exc
)
{
throw
new
Error
(
"Unable to launch target VM: "
+
exc
);
}
catch
(
IllegalConnectorArgumentsException
exc
)
{
throw
new
Error
(
"Internal error: "
+
exc
);
}
catch
(
VMStartException
exc
)
{
throw
new
Error
(
"Target VM failed to initialize: "
+
exc
.
getMessage
());
}
}
private
static
void
addClassWatch
(
VirtualMachine
vm
)
{
EventRequestManager
erm
=
vm
.
eventRequestManager
();
ClassPrepareRequest
classPrepareRequest
=
erm
.
createClassPrepareRequest
();
classPrepareRequest
.
addClassFilter
(
CLASS_NAME
);
classPrepareRequest
.
setEnabled
(
true
);
}
private
static
void
addFieldWatch
(
VirtualMachine
vm
,
ReferenceType
refType
)
{
EventRequestManager
erm
=
vm
.
eventRequestManager
();
Field
field
=
refType
.
fieldByName
(
FIELD_NAME
);
ModificationWatchpointRequest
modificationWatchpointRequest
=
erm
.
createModificationWatchpointRequest
(
field
);
modificationWatchpointRequest
.
setSuspendPolicy
(
EventRequest
.
SUSPEND_EVENT_THREAD
);
modificationWatchpointRequest
.
setEnabled
(
true
);
}
}
class
StreamRedirectThread
extends
Thread
{
private
final
BufferedReader
in
;
private
static
final
int
BUFFER_SIZE
=
2048
;
/**
* Set up for copy.
* @param name Name of the thread
* @param in Stream to copy from
* @param out Stream to copy to
*/
StreamRedirectThread
(
String
name
,
InputStream
in
)
{
super
(
name
);
this
.
in
=
new
BufferedReader
(
new
InputStreamReader
(
in
));
}
/**
* Copy.
*/
public
void
run
()
{
try
{
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
System
.
out
.
println
(
"testvm: "
+
line
);
}
System
.
out
.
flush
();
}
catch
(
IOException
exc
)
{
System
.
err
.
println
(
"Child I/O Transfer - "
+
exc
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录