Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
5bf87e4b
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5bf87e4b
编写于
7月 14, 2008
作者:
T
tbell
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
5c05cfe8
0b12335c
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
417 addition
and
136 deletion
+417
-136
src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java
src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java
+2
-1
src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java
src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java
+130
-125
src/share/classes/com/sun/tools/jdi/VMAction.java
src/share/classes/com/sun/tools/jdi/VMAction.java
+12
-0
src/share/classes/com/sun/tools/jdi/VMState.java
src/share/classes/com/sun/tools/jdi/VMState.java
+11
-2
src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java
src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java
+2
-1
test/com/sun/jdi/MonitorFrameInfo.java
test/com/sun/jdi/MonitorFrameInfo.java
+26
-6
test/com/sun/jdi/ResumeOneThreadTest.java
test/com/sun/jdi/ResumeOneThreadTest.java
+233
-0
test/com/sun/jdi/VMConnection.java
test/com/sun/jdi/VMConnection.java
+1
-1
未找到文件。
src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java
浏览文件 @
5bf87e4b
...
...
@@ -40,11 +40,12 @@ public class MonitorInfoImpl extends MirrorImpl
int
stack_depth
;
MonitorInfoImpl
(
VirtualMachine
vm
,
ObjectReference
mon
,
ThreadReference
thread
,
int
dpth
)
{
ThreadReference
Impl
thread
,
int
dpth
)
{
super
(
vm
);
this
.
monitor
=
mon
;
this
.
thread
=
thread
;
this
.
stack_depth
=
dpth
;
thread
.
addListener
(
this
);
}
...
...
src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java
浏览文件 @
5bf87e4b
...
...
@@ -35,12 +35,34 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
static
final
int
SUSPEND_STATUS_SUSPENDED
=
0x1
;
static
final
int
SUSPEND_STATUS_BREAK
=
0x2
;
private
ThreadGroupReference
threadGroup
;
private
int
suspendedZombieCount
=
0
;
// This is cached only while the VM is suspended
private
static
class
Cache
extends
ObjectReferenceImpl
.
Cache
{
String
name
=
null
;
/*
* Some objects can only be created while a thread is suspended and are valid
* only while the thread remains suspended. Examples are StackFrameImpl
* and MonitorInfoImpl. When the thread resumes, these objects have to be
* marked as invalid so that their methods can throw
* InvalidStackFrameException if they are called. To do this, such objects
* register themselves as listeners of the associated thread. When the
* thread is resumed, its listeners are notified and mark themselves
* invalid.
* Also, note that ThreadReferenceImpl itself caches some info that
* is valid only as long as the thread is suspended. When the thread
* is resumed, that cache must be purged.
* Lastly, note that ThreadReferenceImpl and its super, ObjectReferenceImpl
* cache some info that is only valid as long as the entire VM is suspended.
* If _any_ thread is resumed, this cache must be purged. To handle this,
* both ThreadReferenceImpl and ObjectReferenceImpl register themselves as
* VMListeners so that they get notified when all threads are suspended and
* when any thread is resumed.
*/
// This is cached for the life of the thread
private
ThreadGroupReference
threadGroup
;
// This is cached only while this one thread is suspended. Each time
// the thread is resumed, we clear this and start with a fresh one.
private
static
class
LocalCache
{
JDWP
.
ThreadReference
.
Status
status
=
null
;
List
<
StackFrame
>
frames
=
null
;
int
framesStart
=
-
1
;
...
...
@@ -52,6 +74,17 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
boolean
triedCurrentContended
=
false
;
}
private
LocalCache
localCache
;
private
void
resetLocalCache
()
{
localCache
=
new
LocalCache
();
}
// This is cached only while all threads in the VM are suspended
// Yes, someone could change the name of a thread while it is suspended.
private
static
class
Cache
extends
ObjectReferenceImpl
.
Cache
{
String
name
=
null
;
}
protected
ObjectReferenceImpl
.
Cache
newCache
()
{
return
new
Cache
();
}
...
...
@@ -59,8 +92,10 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
// Listeners - synchronized on vm.state()
private
List
<
WeakReference
<
ThreadListener
>>
listeners
=
new
ArrayList
<
WeakReference
<
ThreadListener
>>();
ThreadReferenceImpl
(
VirtualMachine
aVm
,
long
aRef
)
{
super
(
aVm
,
aRef
);
resetLocalCache
();
vm
.
state
().
addListener
(
this
);
}
...
...
@@ -72,10 +107,24 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
* VMListener implementation
*/
public
boolean
vmNotSuspended
(
VMAction
action
)
{
synchronized
(
vm
.
state
())
{
processThreadAction
(
new
ThreadAction
(
this
,
ThreadAction
.
THREAD_RESUMABLE
));
if
(
action
.
resumingThread
()
==
null
)
{
// all threads are being resumed
synchronized
(
vm
.
state
())
{
processThreadAction
(
new
ThreadAction
(
this
,
ThreadAction
.
THREAD_RESUMABLE
));
}
}
/*
* Othewise, only one thread is being resumed:
* if it is us,
* we have already done our processThreadAction to notify our
* listeners when we processed the resume.
* if it is not us,
* we don't want to notify our listeners
* because we are not being resumed.
*/
return
super
.
vmNotSuspended
(
action
);
}
...
...
@@ -191,23 +240,19 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
}
private
JDWP
.
ThreadReference
.
Status
jdwpStatus
()
{
JDWP
.
ThreadReference
.
Status
status
=
null
;
JDWP
.
ThreadReference
.
Status
myStatus
=
localCache
.
status
;
try
{
Cache
local
=
(
Cache
)
getCache
();
if
(
local
!=
null
)
{
status
=
local
.
status
;
}
if
(
status
==
null
)
{
status
=
JDWP
.
ThreadReference
.
Status
.
process
(
vm
,
this
);
if
(
local
!=
null
)
{
local
.
status
=
status
;
if
(
myStatus
==
null
)
{
myStatus
=
JDWP
.
ThreadReference
.
Status
.
process
(
vm
,
this
);
if
((
myStatus
.
suspendStatus
&
SUSPEND_STATUS_SUSPENDED
)
!=
0
)
{
// thread is suspended, we can cache the status.
localCache
.
status
=
myStatus
;
}
}
}
catch
(
JDWPException
exc
)
{
}
catch
(
JDWPException
exc
)
{
throw
exc
.
toJDIException
();
}
return
s
tatus
;
return
myS
tatus
;
}
public
int
status
()
{
...
...
@@ -245,8 +290,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
public
ThreadGroupReference
threadGroup
()
{
/*
* Thread group can't change, so it's cached more conventionally
* than other things in this class.
* Thread group can't change, so it's cached once and for all.
*/
if
(
threadGroup
==
null
)
{
try
{
...
...
@@ -260,19 +304,10 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
}
public
int
frameCount
()
throws
IncompatibleThreadStateException
{
int
frameCount
=
-
1
;
try
{
Cache
local
=
(
Cache
)
getCache
();
if
(
local
!=
null
)
{
frameCount
=
local
.
frameCount
;
}
if
(
frameCount
==
-
1
)
{
frameCount
=
JDWP
.
ThreadReference
.
FrameCount
if
(
localCache
.
frameCount
==
-
1
)
{
localCache
.
frameCount
=
JDWP
.
ThreadReference
.
FrameCount
.
process
(
vm
,
this
).
frameCount
;
if
(
local
!=
null
)
{
local
.
frameCount
=
frameCount
;
}
}
}
catch
(
JDWPException
exc
)
{
switch
(
exc
.
errorCode
())
{
...
...
@@ -283,7 +318,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
throw
exc
.
toJDIException
();
}
}
return
frameCount
;
return
localCache
.
frameCount
;
}
public
List
<
StackFrame
>
frames
()
throws
IncompatibleThreadStateException
{
...
...
@@ -297,23 +332,25 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
/**
* Is the requested subrange within what has been retrieved?
* local is known to be non-null
* local is known to be non-null. Should only be called from
* a sync method.
*/
private
boolean
isSubrange
(
Cache
local
,
int
start
,
int
length
,
List
frames
)
{
if
(
start
<
local
.
framesStart
)
{
private
boolean
isSubrange
(
LocalCache
localCache
,
int
start
,
int
length
)
{
if
(
start
<
local
Cache
.
framesStart
)
{
return
false
;
}
if
(
length
==
-
1
)
{
return
(
local
.
framesLength
==
-
1
);
return
(
local
Cache
.
framesLength
==
-
1
);
}
if
(
local
.
framesLength
==
-
1
)
{
if
((
start
+
length
)
>
(
local
.
framesStart
+
frames
.
size
()))
{
if
(
localCache
.
framesLength
==
-
1
)
{
if
((
start
+
length
)
>
(
localCache
.
framesStart
+
localCache
.
frames
.
size
()))
{
throw
new
IndexOutOfBoundsException
();
}
return
true
;
}
return
((
start
+
length
)
<=
(
local
.
framesStart
+
local
.
framesLength
));
return
((
start
+
length
)
<=
(
local
Cache
.
framesStart
+
localCache
.
framesLength
));
}
public
List
<
StackFrame
>
frames
(
int
start
,
int
length
)
...
...
@@ -329,51 +366,42 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
* Private version of frames() allows "-1" to specify all
* remaining frames.
*/
private
List
<
StackFrame
>
privateFrames
(
int
start
,
int
length
)
synchronized
private
List
<
StackFrame
>
privateFrames
(
int
start
,
int
length
)
throws
IncompatibleThreadStateException
{
List
<
StackFrame
>
frames
=
null
;
try
{
Cache
local
=
(
Cache
)
getCache
();
if
(
local
!=
null
)
{
frames
=
local
.
frames
;
}
if
(
frames
==
null
||
!
isSubrange
(
local
,
start
,
length
,
frames
))
{
// Lock must be held while creating stack frames so if that two threads
// do this at the same time, one won't clobber the subset created by the other.
try
{
if
(
localCache
.
frames
==
null
||
!
isSubrange
(
localCache
,
start
,
length
))
{
JDWP
.
ThreadReference
.
Frames
.
Frame
[]
jdwpFrames
=
JDWP
.
ThreadReference
.
Frames
.
process
(
vm
,
this
,
start
,
length
).
frames
;
process
(
vm
,
this
,
start
,
length
).
frames
;
int
count
=
jdwpFrames
.
length
;
frames
=
new
ArrayList
<
StackFrame
>(
count
);
// Lock must be held while creating stack frames.
// so that a resume will not resume a partially
// created stack.
synchronized
(
vm
.
state
())
{
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
if
(
jdwpFrames
[
i
].
location
==
null
)
{
throw
new
InternalException
(
"Invalid frame location"
);
}
StackFrame
frame
=
new
StackFrameImpl
(
vm
,
this
,
jdwpFrames
[
i
].
frameID
,
jdwpFrames
[
i
].
location
);
// Add to the frame list
frames
.
add
(
frame
);
localCache
.
frames
=
new
ArrayList
<
StackFrame
>(
count
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
if
(
jdwpFrames
[
i
].
location
==
null
)
{
throw
new
InternalException
(
"Invalid frame location"
);
}
StackFrame
frame
=
new
StackFrameImpl
(
vm
,
this
,
jdwpFrames
[
i
].
frameID
,
jdwpFrames
[
i
].
location
);
// Add to the frame list
localCache
.
frames
.
add
(
frame
);
}
if
(
local
!=
null
)
{
local
.
frames
=
frames
;
local
.
framesStart
=
start
;
local
.
framesLength
=
length
;
}
localCache
.
framesStart
=
start
;
localCache
.
framesLength
=
length
;
return
Collections
.
unmodifiableList
(
localCache
.
frames
);
}
else
{
int
fromIndex
=
start
-
local
.
framesStart
;
int
fromIndex
=
start
-
local
Cache
.
framesStart
;
int
toIndex
;
if
(
length
==
-
1
)
{
toIndex
=
frames
.
size
()
-
fromIndex
;
toIndex
=
localCache
.
frames
.
size
()
-
fromIndex
;
}
else
{
toIndex
=
fromIndex
+
length
;
}
frames
=
frames
.
subList
(
fromIndex
,
toIndex
);
return
Collections
.
unmodifiableList
(
localCache
.
frames
.
subList
(
fromIndex
,
toIndex
)
);
}
}
catch
(
JDWPException
exc
)
{
switch
(
exc
.
errorCode
())
{
...
...
@@ -384,28 +412,18 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
throw
exc
.
toJDIException
();
}
}
return
Collections
.
unmodifiableList
(
frames
);
}
public
List
<
ObjectReference
>
ownedMonitors
()
throws
IncompatibleThreadStateException
{
List
<
ObjectReference
>
monitors
=
null
;
try
{
Cache
local
=
(
Cache
)
getCache
();
if
(
local
!=
null
)
{
monitors
=
local
.
ownedMonitors
;
}
if
(
monitors
==
null
)
{
monitors
=
Arrays
.
asList
(
if
(
localCache
.
ownedMonitors
==
null
)
{
localCache
.
ownedMonitors
=
Arrays
.
asList
(
(
ObjectReference
[])
JDWP
.
ThreadReference
.
OwnedMonitors
.
process
(
vm
,
this
).
owned
);
if
(
local
!=
null
)
{
local
.
ownedMonitors
=
monitors
;
if
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
)
{
vm
.
printTrace
(
description
()
+
" temporarily caching owned monitors"
+
" (count = "
+
monitors
.
size
()
+
")"
);
}
if
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
)
{
vm
.
printTrace
(
description
()
+
" temporarily caching owned monitors"
+
" (count = "
+
localCache
.
ownedMonitors
.
size
()
+
")"
);
}
}
}
catch
(
JDWPException
exc
)
{
...
...
@@ -417,29 +435,22 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
throw
exc
.
toJDIException
();
}
}
return
m
onitors
;
return
localCache
.
ownedM
onitors
;
}
public
ObjectReference
currentContendedMonitor
()
throws
IncompatibleThreadStateException
{
ObjectReference
monitor
=
null
;
try
{
Cache
local
=
(
Cache
)
getCache
();
if
(
local
!=
null
&&
local
.
triedCurrentContended
)
{
monitor
=
local
.
contendedMonitor
;
}
else
{
monitor
=
JDWP
.
ThreadReference
.
CurrentContendedMonitor
.
if
(
localCache
.
contendedMonitor
==
null
&&
!
localCache
.
triedCurrentContended
)
{
localCache
.
contendedMonitor
=
JDWP
.
ThreadReference
.
CurrentContendedMonitor
.
process
(
vm
,
this
).
monitor
;
if
(
local
!=
null
)
{
local
.
triedCurrentContended
=
true
;
local
.
contendedMonitor
=
monitor
;
if
((
monitor
!=
null
)
&&
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
))
{
vm
.
printTrace
(
description
()
+
" temporarily caching contended monitor"
+
" (id = "
+
monitor
.
uniqueID
()
+
")"
);
}
localCache
.
triedCurrentContended
=
true
;
if
((
localCache
.
contendedMonitor
!=
null
)
&&
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
))
{
vm
.
printTrace
(
description
()
+
" temporarily caching contended monitor"
+
" (id = "
+
localCache
.
contendedMonitor
.
uniqueID
()
+
")"
);
}
}
}
catch
(
JDWPException
exc
)
{
...
...
@@ -450,40 +461,31 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
throw
exc
.
toJDIException
();
}
}
return
m
onitor
;
return
localCache
.
contendedM
onitor
;
}
public
List
<
MonitorInfo
>
ownedMonitorsAndFrames
()
throws
IncompatibleThreadStateException
{
List
<
MonitorInfo
>
monitors
=
null
;
try
{
Cache
local
=
(
Cache
)
getCache
();
if
(
local
!=
null
)
{
monitors
=
local
.
ownedMonitorsInfo
;
}
if
(
monitors
==
null
)
{
if
(
localCache
.
ownedMonitorsInfo
==
null
)
{
JDWP
.
ThreadReference
.
OwnedMonitorsStackDepthInfo
.
monitor
[]
minfo
;
minfo
=
JDWP
.
ThreadReference
.
OwnedMonitorsStackDepthInfo
.
process
(
vm
,
this
).
owned
;
monitors
=
new
ArrayList
<
MonitorInfo
>(
minfo
.
length
);
localCache
.
ownedMonitorsInfo
=
new
ArrayList
<
MonitorInfo
>(
minfo
.
length
);
for
(
int
i
=
0
;
i
<
minfo
.
length
;
i
++)
{
JDWP
.
ThreadReference
.
OwnedMonitorsStackDepthInfo
.
monitor
mi
=
minfo
[
i
];
MonitorInfo
mon
=
new
MonitorInfoImpl
(
vm
,
minfo
[
i
].
monitor
,
this
,
minfo
[
i
].
stack_depth
);
monitors
.
add
(
mon
);
localCache
.
ownedMonitorsInfo
.
add
(
mon
);
}
if
(
local
!=
null
)
{
local
.
ownedMonitorsInfo
=
monitors
;
if
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
)
{
vm
.
printTrace
(
description
()
+
" temporarily caching owned monitors"
+
" (count = "
+
monitors
.
size
()
+
")"
);
if
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
)
{
vm
.
printTrace
(
description
()
+
" temporarily caching owned monitors"
+
" (count = "
+
localCache
.
ownedMonitorsInfo
.
size
()
+
")"
);
}
}
}
}
catch
(
JDWPException
exc
)
{
switch
(
exc
.
errorCode
())
{
case
JDWP
.
Error
.
THREAD_NOT_SUSPENDED
:
...
...
@@ -493,7 +495,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
throw
exc
.
toJDIException
();
}
}
return
monitors
;
return
localCache
.
ownedMonitorsInfo
;
}
public
void
popFrames
(
StackFrame
frame
)
throws
IncompatibleThreadStateException
{
...
...
@@ -511,7 +513,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
}
public
void
forceEarlyReturn
(
Value
returnValue
)
throws
InvalidTypeException
,
ClassNotLoadedException
,
ClassNotLoadedException
,
IncompatibleThreadStateException
{
if
(!
vm
.
canForceEarlyReturn
())
{
throw
new
UnsupportedOperationException
(
...
...
@@ -604,6 +606,9 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
iter
.
remove
();
}
}
// Discard our local cache
resetLocalCache
();
}
}
}
src/share/classes/com/sun/tools/jdi/VMAction.java
浏览文件 @
5bf87e4b
...
...
@@ -38,10 +38,18 @@ class VMAction extends EventObject {
static
final
int
VM_NOT_SUSPENDED
=
2
;
int
id
;
ThreadReference
resumingThread
;
VMAction
(
VirtualMachine
vm
,
int
id
)
{
this
(
vm
,
null
,
id
);
}
// For id = VM_NOT_SUSPENDED, if resumingThread != null, then it is
// the only thread that is being resumed.
VMAction
(
VirtualMachine
vm
,
ThreadReference
resumingThread
,
int
id
)
{
super
(
vm
);
this
.
id
=
id
;
this
.
resumingThread
=
resumingThread
;
}
VirtualMachine
vm
()
{
return
(
VirtualMachine
)
getSource
();
...
...
@@ -49,4 +57,8 @@ class VMAction extends EventObject {
int
id
()
{
return
id
;
}
ThreadReference
resumingThread
()
{
return
resumingThread
;
}
}
src/share/classes/com/sun/tools/jdi/VMState.java
浏览文件 @
5bf87e4b
...
...
@@ -115,17 +115,26 @@ class VMState {
return
stream
;
}
/**
* All threads are resuming
*/
void
thaw
()
{
thaw
(
null
);
}
/**
* Tell listeners to invalidate suspend-sensitive caches.
* If resumingThread != null, then only that thread is being
* resumed.
*/
synchronized
void
thaw
()
{
synchronized
void
thaw
(
ThreadReference
resumingThread
)
{
if
(
cache
!=
null
)
{
if
((
vm
.
traceFlags
&
vm
.
TRACE_OBJREFS
)
!=
0
)
{
vm
.
printTrace
(
"Clearing VM suspended cache"
);
}
disableCache
();
}
processVMAction
(
new
VMAction
(
vm
,
VMAction
.
VM_NOT_SUSPENDED
));
processVMAction
(
new
VMAction
(
vm
,
resumingThread
,
VMAction
.
VM_NOT_SUSPENDED
));
}
private
synchronized
void
processVMAction
(
VMAction
action
)
{
...
...
src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java
浏览文件 @
5bf87e4b
...
...
@@ -146,8 +146,9 @@ class VirtualMachineImpl extends MirrorImpl
public
boolean
threadResumable
(
ThreadAction
action
)
{
/*
* If any thread is resumed, the VM is considered not suspended.
* Just one thread is being resumed so pass it to thaw.
*/
state
.
thaw
();
state
.
thaw
(
action
.
thread
()
);
return
true
;
}
...
...
test/com/sun/jdi/MonitorFrameInfo.java
浏览文件 @
5bf87e4b
...
...
@@ -25,7 +25,8 @@
* @test
* @bug 6230699
* @summary Test ThreadReference.ownedMonitorsAndFrames()
*
* @bug 6701700
* @summary MonitorInfo objects aren't invalidated when the owning thread is resumed
* @author Swamy Venkataramanappa
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
...
...
@@ -100,15 +101,15 @@ public class MonitorFrameInfo extends TestScaffold {
if
(!
mainThread
.
frame
(
0
).
location
().
method
().
name
()
.
equals
(
"foo3"
))
{
failure
(
"frame failed"
);
failure
(
"
FAILED:
frame failed"
);
}
if
(
mainThread
.
frames
().
size
()
!=
(
initialSize
+
3
))
{
failure
(
"frames size failed"
);
failure
(
"
FAILED:
frames size failed"
);
}
if
(
mainThread
.
frames
().
size
()
!=
mainThread
.
frameCount
())
{
failure
(
"frames size not equal to frameCount"
);
failure
(
"
FAILED:
frames size not equal to frameCount"
);
}
/* Test monitor frame info.
...
...
@@ -119,13 +120,32 @@ public class MonitorFrameInfo extends TestScaffold {
if
(
monitors
.
size
()
!=
expectedCount
)
{
failure
(
"monitors count is not equal to expected count"
);
}
MonitorInfo
mon
=
null
;
for
(
int
j
=
0
;
j
<
monitors
.
size
();
j
++)
{
MonitorInfo
mon
=
(
MonitorInfo
)
monitors
.
get
(
j
);
mon
=
(
MonitorInfo
)
monitors
.
get
(
j
);
System
.
out
.
println
(
"Monitor obj "
+
mon
.
monitor
()
+
"depth ="
+
mon
.
stackDepth
());
if
(
mon
.
stackDepth
()
!=
expectedDepth
[
j
])
{
failure
(
"monitor stack depth is not equal to expected depth"
);
failure
(
"
FAILED:
monitor stack depth is not equal to expected depth"
);
}
}
// The last gotten monInfo is in mon. When we resume the thread,
// it should become invalid. We will step out of the top frame
// so that the frame depth in this mon object will no longer be correct.
// That is why the monInfo's have to become invalid when the thread is
// resumed.
stepOut
(
mainThread
);
boolean
ok
=
false
;
try
{
System
.
out
.
println
(
"*** Saved Monitor obj "
+
mon
.
monitor
()
+
"depth ="
+
mon
.
stackDepth
());
}
catch
(
InvalidStackFrameException
ee
)
{
// ok
ok
=
true
;
System
.
out
.
println
(
"Got expected InvalidStackFrameException after a resume"
);
}
if
(!
ok
)
{
failure
(
"FAILED: MonitorInfo object was not invalidated by a resume"
);
}
}
else
{
System
.
out
.
println
(
"can not get monitors frame info"
);
}
...
...
test/com/sun/jdi/ResumeOneThreadTest.java
0 → 100644
浏览文件 @
5bf87e4b
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6700889
* @summary Thread resume invalidates all stack frames, even from other threads
*
* @author jjh
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g ResumeOneThreadTest.java
* @run main ResumeOneThreadTest
*/
import
com.sun.jdi.*
;
import
com.sun.jdi.event.*
;
import
com.sun.jdi.request.*
;
import
java.util.*
;
class
ResumeOneThreadTarg
extends
Thread
{
static
String
name1
=
"Thread 1"
;
static
String
name2
=
"Thread 2"
;
public
ResumeOneThreadTarg
(
String
name
)
{
super
(
name
);
}
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
" Debuggee: Howdy!"
);
ResumeOneThreadTarg
t1
=
new
ResumeOneThreadTarg
(
name1
);
ResumeOneThreadTarg
t2
=
new
ResumeOneThreadTarg
(
name2
);
t1
.
start
();
t2
.
start
();
}
// This just starts two threads. Each runs to a bkpt.
public
void
run
()
{
if
(
getName
().
equals
(
name1
))
{
run1
();
}
else
{
run2
();
}
}
public
void
bkpt1
(
String
p1
)
{
System
.
out
.
println
(
" Debuggee: bkpt 1"
);
}
public
void
run1
()
{
bkpt1
(
"Hello Alviso!"
);
}
public
void
bkpt2
()
{
System
.
out
.
println
(
" Debuggee: bkpt 2"
);
}
public
void
run2
()
{
bkpt2
();
}
}
/********** test program **********/
public
class
ResumeOneThreadTest
extends
TestScaffold
{
ReferenceType
targetClass
;
ThreadReference
mainThread
;
BreakpointRequest
request1
;
BreakpointRequest
request2
;
ThreadReference
thread1
=
null
;
ThreadReference
thread2
=
null
;;
boolean
theVMisDead
=
false
;
ResumeOneThreadTest
(
String
args
[])
{
super
(
args
);
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
ResumeOneThreadTest
(
args
).
startTests
();
}
synchronized
public
void
breakpointReached
(
BreakpointEvent
event
)
{
println
(
"-- Got bkpt at: "
+
event
.
location
());
ThreadReference
eventThread
=
event
.
thread
();
if
(
eventThread
.
name
().
equals
(
ResumeOneThreadTarg
.
name1
))
{
thread1
=
eventThread
;
}
if
(
eventThread
.
name
().
equals
(
ResumeOneThreadTarg
.
name2
))
{
thread2
=
eventThread
;
}
}
public
void
vmDied
(
VMDeathEvent
event
)
{
theVMisDead
=
true
;
}
synchronized
public
void
eventSetComplete
(
EventSet
set
)
{
if
(
theVMisDead
)
{
return
;
}
if
(
thread1
==
null
||
thread2
==
null
)
{
// Don't do a set.resume(), just let the other thread
// keep running until it hits its bkpt.
return
;
}
// Both threads are stopped at their bkpts. Get a StackFrame from
// Thread 1 then resume Thread 2 and verify that the saved StackFrame is
// still valid.
// suspend everything.
println
(
"-- All threads suspended"
);
vm
().
suspend
();
StackFrame
t1sf0
=
null
;
try
{
t1sf0
=
thread1
.
frame
(
0
);
}
catch
(
IncompatibleThreadStateException
ee
)
{
failure
(
"FAILED: Exception: "
+
ee
);
}
println
(
"-- t1sf0 args: "
+
t1sf0
.
getArgumentValues
());
// Ok, we have a StackFrame for thread 1. Resume just thread 2
// Note that thread 2 has been suspended twice - by the SUSPEND_ALL
// bkpt, and by the above vm().suspend(), so we have to resume
// it twice.
request2
.
disable
();
thread2
.
resume
();
thread2
.
resume
();
println
(
"-- Did Resume on thread 2"
);
// Can we get frames for thread1?
try
{
StackFrame
t1sf0_1
=
thread1
.
frame
(
0
);
if
(!
t1sf0
.
equals
(
t1sf0_1
))
{
failure
(
"FAILED: Got a different frame 0 for thread 1 after resuming thread 2"
);
}
}
catch
(
IncompatibleThreadStateException
ee
)
{
failure
(
"FAILED: Could not get frames for thread 1: Exception: "
+
ee
);
}
catch
(
Exception
ee
)
{
failure
(
"FAILED: Could not get frames for thread 1: Exception: "
+
ee
);
}
try
{
println
(
"-- t1sf0 args: "
+
t1sf0
.
getArgumentValues
());
}
catch
(
InvalidStackFrameException
ee
)
{
// This is the failure.
failure
(
"FAILED Got InvalidStackFrameException"
);
vm
().
dispose
();
throw
(
ee
);
}
// Let the debuggee finish
request1
.
disable
();
thread1
.
resume
();
vm
().
resume
();
println
(
"--------------"
);
}
/********** test core **********/
protected
void
runTests
()
throws
Exception
{
/*
* Get to the top of main()
* to determine targetClass and mainThread
*/
BreakpointEvent
bpe
=
startToMain
(
"ResumeOneThreadTarg"
);
targetClass
=
bpe
.
location
().
declaringType
();
mainThread
=
bpe
.
thread
();
EventRequestManager
erm
=
vm
().
eventRequestManager
();
final
Thread
mainThread
=
Thread
.
currentThread
();
/*
* Set event requests
*/
Location
loc1
=
findMethod
(
targetClass
,
"bkpt1"
,
"(Ljava/lang/String;)V"
).
location
();
request1
=
erm
.
createBreakpointRequest
(
loc1
);
request1
.
setSuspendPolicy
(
EventRequest
.
SUSPEND_EVENT_THREAD
);
request1
.
enable
();
Location
loc2
=
findMethod
(
targetClass
,
"bkpt2"
,
"()V"
).
location
();
request2
=
erm
.
createBreakpointRequest
(
loc2
);
request2
.
setSuspendPolicy
(
EventRequest
.
SUSPEND_EVENT_THREAD
);
request2
.
enable
();
/*
* resume the target, listening for events
*/
listenUntilVMDisconnect
();
/*
* deal with results of test
* if anything has called failure("foo") testFailed will be true
*/
if
(!
testFailed
)
{
println
(
"ResumeOneThreadTest: passed"
);
}
else
{
throw
new
Exception
(
"ResumeOneThreadTest: failed"
);
}
}
}
test/com/sun/jdi/VMConnection.java
浏览文件 @
5bf87e4b
...
...
@@ -115,7 +115,7 @@ class VMConnection {
return
cmdLine
;
}
// Insert the options at position 1. Blanks in args are not allowed!
String
[]
v1
=
opts
.
split
(
" "
);
String
[]
v1
=
opts
.
split
(
"
+
"
);
String
[]
retVal
=
new
String
[
cmdLine
.
length
+
v1
.
length
];
retVal
[
0
]
=
cmdLine
[
0
];
System
.
arraycopy
(
v1
,
0
,
retVal
,
1
,
v1
.
length
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录