Skip to content

Commit 0251f1f

Browse files
committed
Replace the debugger controller instance in jdwp context and vm event listener, and clean up field and method breakpoints on session dispose.
1 parent d6ddf70 commit 0251f1f

File tree

12 files changed

+81
-12
lines changed

12 files changed

+81
-12
lines changed

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/FieldRef.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,6 @@ public interface FieldRef {
114114
* @return true if this field has any breakpoints, false otherwise
115115
*/
116116
boolean hasActiveBreakpoint();
117+
118+
void disposeFieldBreakpoint();
117119
}

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.oracle.truffle.api.frame.Frame;
3030
import com.oracle.truffle.api.nodes.Node;
3131
import com.oracle.truffle.api.nodes.RootNode;
32+
import com.oracle.truffle.espresso.jdwp.impl.DebuggerController;
3233

3334
/**
3435
* Interface that defines required methods for a guest language when implementing JDWP.
@@ -500,4 +501,6 @@ public interface JDWPContext {
500501
Object allocateInstance(KlassRef klass);
501502

502503
void steppingInProgress(Thread t, boolean value);
504+
505+
void replaceController(DebuggerController newController);
503506
}

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ public interface MethodRef {
232232
*/
233233
boolean hasActiveHook();
234234

235+
void disposeHooks();
236+
235237
/**
236238
* Determine if this method is obsolete. A method is obsolete if it has been replaced by a
237239
* non-equivalent method using the RedefineClasses command. The original and redefined methods

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/VMEventListenerImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ public void activate(Object mainThread, DebuggerController control, JDWPContext
9090
this.ids = context.getIds();
9191
}
9292

93+
public void replaceController(DebuggerController newController) {
94+
this.debuggerController = newController;
95+
}
96+
9397
@Override
9498
public void onDetach() {
9599
// free up request, to avoid attempting to send anything further

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/BreakpointInfo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,8 @@ public interface BreakpointInfo {
5858
void addSuspendPolicy(byte suspendPolicy);
5959

6060
byte getSuspendPolicy();
61+
62+
default void dispose() {
63+
// do nothing by default
64+
}
6165
}

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/DebuggerController.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ public void reInitialize() {
157157
DebuggerController newController = new DebuggerController(jdwpLogger);
158158
newController.truffleContext = truffleContext;
159159
newController.initialize(debugger, options, context, initialThread, eventListener);
160+
context.replaceController(newController);
160161
assert newController.setupState != null;
161162

162163
if (newController.setupState.fatalConnectionError) {
@@ -186,6 +187,10 @@ public void reset(boolean prepareForReconnect) {
186187
// existence state.
187188
resetting.lockInterruptibly();
188189

190+
// end the current debugger session to avoid hitting any further breakpoints
191+
// when resuming all threads
192+
endSession();
193+
189194
currentReceiverThread = receiverThread;
190195

191196
// Close the server socket used to listen for transport dt_socket.
@@ -207,16 +212,14 @@ public void reset(boolean prepareForReconnect) {
207212
// re-enable GC for all objects
208213
getGCPrevention().clearAll();
209214

210-
// end the current debugger session to avoid hitting any further breakpoints
211-
// when resuming all threads
212-
endSession();
213-
214-
// resume all threads
215-
forceResumeAll();
215+
eventFilters.clearAll();
216216

217217
// Now, close the socket, which will force the receiver thread to complete eventually.
218218
// Note that we might run this code in the receiver thread, so we can't simply join.
219219
closeSocket();
220+
221+
// resume all threads
222+
forceResumeAll();
220223
} catch (InterruptedException e) {
221224
Thread.currentThread().interrupt();
222225
} finally {
@@ -822,8 +825,8 @@ private void lockThread(Object thread, boolean forceSuspend, List<Callable<Void>
822825
while (!Thread.currentThread().isInterrupted()) {
823826
try {
824827
synchronized (lock) {
825-
if (!lock.isLocked()) {
826-
// released from other thread, so break loop
828+
if (!lock.isLocked() || !connection.isOpen()) {
829+
// released from other thread or session ended, so break loop
827830
break;
828831
}
829832
// no reason to hold a hard suspension status, since now

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/EventFilters.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,20 @@ public RequestFilter getRequestFilter(int requestId) {
6262
readLock.unlock();
6363
}
6464
}
65+
66+
public void clearAll() {
67+
try {
68+
lock.writeLock().lock();
69+
// traverse all filters and clear all registered breakpoint information
70+
for (RequestFilter requestFilter : requestFilters) {
71+
BreakpointInfo breakpointInfo = requestFilter.getBreakpointInfo();
72+
if (breakpointInfo != null) {
73+
breakpointInfo.dispose();
74+
}
75+
}
76+
requestFilters = new RequestFilter[0];
77+
} finally {
78+
lock.writeLock().unlock();
79+
}
80+
}
6581
}

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/FieldBreakpointInfo.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,9 @@ public boolean isModificationBreakpoint() {
6363
public boolean isAccessBreakpoint() {
6464
return accessBreakpoint;
6565
}
66+
67+
@Override
68+
public void dispose() {
69+
field.disposeFieldBreakpoint();
70+
}
6671
}

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/MethodBreakpointInfo.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,11 @@ public boolean onMethodEnter(@SuppressWarnings("unused") MethodRef method, @Supp
6363
public boolean onMethodExit(@SuppressWarnings("unused") MethodRef method, @SuppressWarnings("unused") Object returnValue) {
6464
return isMethodExit;
6565
}
66+
67+
@Override
68+
public void dispose() {
69+
for (MethodRef method : methods) {
70+
method.disposeHooks();
71+
}
72+
}
6673
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Field.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,11 +926,16 @@ public final void removeFieldBreakpointInfo(int requestId) {
926926
// remove index 1, but keep info at index 0
927927
temp[0] = infos[0];
928928
infos = temp;
929-
return;
930929
}
931930
}
932931
}
933932

933+
@Override
934+
public void disposeFieldBreakpoint() {
935+
hasActiveBreakpoints.set(false);
936+
infos = null;
937+
}
938+
934939
public void setCompatibleField(@SuppressWarnings("unused") Field field) {
935940
// only applicable to RedefineAddedFields
936941
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,11 @@ public synchronized void removeActiveHook(MethodHook hook) {
11041104
}
11051105
}
11061106

1107+
public synchronized void disposeHooks() {
1108+
hasActiveHook.set(false);
1109+
hooks = MethodHook.EMPTY;
1110+
}
1111+
11071112
public SharedRedefinitionContent redefine(ObjectKlass.KlassVersion klassVersion, ParserMethod newMethod, ParserKlass newKlass, Ids<Object> ids) {
11081113
// install the new method version immediately
11091114
LinkedMethod newLinkedMethod = new LinkedMethod(newMethod);
@@ -1848,6 +1853,11 @@ public void removedMethodHook(MethodHook hook) {
18481853
getMethod().removeActiveHook(hook);
18491854
}
18501855

1856+
@Override
1857+
public void disposeHooks() {
1858+
getMethod().disposeHooks();
1859+
}
1860+
18511861
@Override
18521862
public boolean hasActiveHook() {
18531863
return getMethod().hasActiveHook();

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,20 @@ public final class JDWPContextImpl implements JDWPContext {
9898
private RedefinitionPluginHandler redefinitionPluginHandler;
9999
private final ArrayList<ReloadingAction> classInitializerActions = new ArrayList<>(1);
100100
private DebuggerController controller;
101+
private VMEventListenerImpl vmEventListener;
101102

102103
public JDWPContextImpl(EspressoContext context) {
103104
this.context = context;
104105
this.ids = new Ids<>(StaticObject.NULL);
105106
this.innerClassRedefiner = new InnerClassRedefiner(context);
106107
}
107108

108-
public void jdwpInit(TruffleLanguage.Env env, Object mainThread, VMEventListenerImpl vmEventListener) {
109+
public void jdwpInit(TruffleLanguage.Env env, Object mainThread, VMEventListenerImpl eventListener) {
109110
Debugger debugger = env.lookup(env.getInstruments().get("debugger"), Debugger.class);
110111
this.controller = env.lookup(env.getInstruments().get(JDWPInstrument.ID), DebuggerController.class);
111-
vmEventListener.activate(mainThread, controller, this);
112-
controller.initialize(debugger, context.getEspressoEnv().JDWPOptions, this, mainThread, vmEventListener);
112+
vmEventListener = eventListener;
113+
eventListener.activate(mainThread, controller, this);
114+
controller.initialize(debugger, context.getEspressoEnv().JDWPOptions, this, mainThread, eventListener);
113115
redefinitionPluginHandler = RedefinitionPluginHandler.create(context);
114116
classRedefinition = context.createClassRedefinition(ids, redefinitionPluginHandler);
115117
}
@@ -120,6 +122,12 @@ public void finalizeContext() {
120122
}
121123
}
122124

125+
@Override
126+
public void replaceController(DebuggerController newController) {
127+
this.controller = newController;
128+
vmEventListener.replaceController(newController);
129+
}
130+
123131
@Override
124132
public Ids<Object> getIds() {
125133
return ids;

0 commit comments

Comments
 (0)