Skip to content

Commit 4ac9cdd

Browse files
authored
Merge branch 'master' into andy_user_error
2 parents e0b8286 + 285040d commit 4ac9cdd

10 files changed

Lines changed: 488 additions & 9 deletions

File tree

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public void close() throws Exception {
7474
subscriptions().forEach(subscription -> {
7575
subscription.dispose();
7676
});
77+
requests.clear();
78+
subscriptions.clear();
7779
}
7880

7981
// IBreakpoint
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.core;
13+
14+
import com.sun.jdi.AbsentInformationException;
15+
import com.sun.jdi.IncompatibleThreadStateException;
16+
import com.sun.jdi.ReferenceType;
17+
import com.sun.jdi.StackFrame;
18+
19+
public final class StackFrameUtility {
20+
21+
public static boolean isNative(StackFrame frame) {
22+
return frame.location().method().isNative();
23+
}
24+
25+
/**
26+
* Pop a StackFrame from its thread.
27+
*
28+
* @param frame
29+
* the StackFrame will be popped
30+
* @return true if succeeded
31+
*/
32+
public static boolean pop(StackFrame frame) {
33+
try {
34+
frame.thread().popFrames(frame);
35+
} catch (IncompatibleThreadStateException e) {
36+
return false;
37+
}
38+
return true;
39+
}
40+
41+
public static String getName(StackFrame frame) {
42+
return frame.location().method().name();
43+
}
44+
45+
public static String getSignature(StackFrame frame) {
46+
return frame.location().method().signature();
47+
}
48+
49+
public static boolean isObsolete(StackFrame frame) {
50+
return frame.location().method().isObsolete();
51+
}
52+
53+
/**
54+
* Get the StackFrame associated source file path.
55+
*
56+
* @param frame
57+
* StackFrame for the source path
58+
* @return the source file path
59+
*/
60+
public static String getSourcePath(StackFrame frame) {
61+
try {
62+
return frame.location().sourcePath();
63+
} catch (AbsentInformationException e) {
64+
// Ignore it
65+
}
66+
return null;
67+
}
68+
69+
public static ReferenceType getDeclaringType(StackFrame frame) {
70+
return frame.location().method().declaringType();
71+
}
72+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.core.adapter;
13+
14+
import java.util.List;
15+
import java.util.concurrent.CompletableFuture;
16+
17+
public interface IHotCodeReplaceProvider extends IProvider {
18+
CompletableFuture<List<String>> redefineClasses();
19+
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IProvider.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,15 @@
1313

1414
import java.util.Map;
1515

16-
import com.microsoft.java.debug.core.IDebugSession;
17-
1816
public interface IProvider {
1917
/**
2018
* Initialize this provider.
21-
* @param debugSession
22-
* The associated debug session
19+
*
20+
* @param debugContext
21+
* The associated debug context
2322
* @param options
2423
* the options
2524
*/
26-
default void initialize(IDebugSession debugSession, Map<String, Object> options) {
25+
default void initialize(IDebugAdapterContext debugContext, Map<String, Object> options) {
2726
}
2827
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.microsoft.java.debug.core.adapter.ErrorCode;
2929
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
3030
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
31+
import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider;
3132
import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider;
3233
import com.microsoft.java.debug.core.adapter.IVirtualMachineManagerProvider;
3334
import com.microsoft.java.debug.core.protocol.Events;
@@ -86,7 +87,9 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
8687
options.put(Constants.PROJECTNAME, attachArguments.projectName);
8788
}
8889
ISourceLookUpProvider sourceProvider = context.getProvider(ISourceLookUpProvider.class);
89-
sourceProvider.initialize(context.getDebugSession(), options);
90+
sourceProvider.initialize(context, options);
91+
IHotCodeReplaceProvider hcrProvider = context.getProvider(IHotCodeReplaceProvider.class);
92+
hcrProvider.initialize(context, options);
9093

9194
// Send an InitializedEvent to indicate that the debugger is ready to accept configuration requests
9295
// (e.g. SetBreakpointsRequest, SetExceptionBreakpointsRequest).

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.microsoft.java.debug.core.adapter.ErrorCode;
4343
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
4444
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
45+
import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider;
4546
import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider;
4647
import com.microsoft.java.debug.core.adapter.IVirtualMachineManagerProvider;
4748
import com.microsoft.java.debug.core.adapter.ProcessConsole;
@@ -112,7 +113,9 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
112113
if (launchArguments.projectName != null) {
113114
options.put(Constants.PROJECTNAME, launchArguments.projectName);
114115
}
115-
sourceProvider.initialize(context.getDebugSession(), options);
116+
sourceProvider.initialize(context, options);
117+
IHotCodeReplaceProvider hcrProvider = context.getProvider(IHotCodeReplaceProvider.class);
118+
hcrProvider.initialize(context, options);
116119

117120
// Send an InitializedEvent to indicate that the debugger is ready to accept configuration requests
118121
// (e.g. SetBreakpointsRequest, SetExceptionBreakpointsRequest).

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,21 @@
1515
import java.util.Arrays;
1616
import java.util.List;
1717
import java.util.concurrent.CompletableFuture;
18+
import java.util.logging.Level;
19+
import java.util.logging.Logger;
1820

1921
import org.apache.commons.io.FilenameUtils;
2022
import org.apache.commons.lang3.StringUtils;
2123

24+
import com.microsoft.java.debug.core.Configuration;
2225
import com.microsoft.java.debug.core.DebugException;
2326
import com.microsoft.java.debug.core.IBreakpoint;
2427
import com.microsoft.java.debug.core.adapter.AdapterUtils;
2528
import com.microsoft.java.debug.core.adapter.BreakpointManager;
2629
import com.microsoft.java.debug.core.adapter.ErrorCode;
2730
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
2831
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
32+
import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider;
2933
import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider;
3034
import com.microsoft.java.debug.core.protocol.Events;
3135
import com.microsoft.java.debug.core.protocol.Messages.Response;
@@ -36,6 +40,9 @@
3640
import com.microsoft.java.debug.core.protocol.Types;
3741

3842
public class SetBreakpointsRequestHandler implements IDebugRequestHandler {
43+
44+
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
45+
3946
private BreakpointManager manager = new BreakpointManager();
4047

4148
@Override
@@ -77,6 +84,12 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
7784
return AdapterUtils.createAsyncErrorResponse(response, ErrorCode.SET_BREAKPOINT_FAILURE,
7885
String.format("Failed to setBreakpoint. Reason: '%s' is an invalid path.", bpArguments.source.path));
7986
}
87+
88+
if (bpArguments.sourceModified) {
89+
IHotCodeReplaceProvider hcrProvider = context.getProvider(IHotCodeReplaceProvider.class);
90+
hcrProvider.redefineClasses().thenAcceptAsync((List<String> result) -> reinstallBreakpoints(context, result));
91+
}
92+
8093
try {
8194
List<Types.Breakpoint> res = new ArrayList<>();
8295
IBreakpoint[] toAdds = this.convertClientBreakpointsToDebugger(sourcePath, bpArguments.breakpoints, context);
@@ -135,4 +148,24 @@ private IBreakpoint[] convertClientBreakpointsToDebugger(String sourceFile, Type
135148
return breakpoints;
136149
}
137150

151+
private void reinstallBreakpoints(IDebugAdapterContext context, List<String> typenames) {
152+
if (typenames == null || typenames.isEmpty()) {
153+
return;
154+
}
155+
IBreakpoint[] breakpoints = manager.getBreakpoints();
156+
157+
for (IBreakpoint breakpoint : breakpoints) {
158+
if (typenames.contains(breakpoint.className())) {
159+
try {
160+
breakpoint.close();
161+
breakpoint.install().thenAccept(bp -> {
162+
Events.BreakpointEvent bpEvent = new Events.BreakpointEvent("new", this.convertDebuggerBreakpointToClient(bp, context));
163+
context.getProtocolServer().sendEvent(bpEvent);
164+
});
165+
} catch (Exception e) {
166+
logger.log(Level.SEVERE, String.format("Remove breakpoint exception: %s", e.toString()), e);
167+
}
168+
}
169+
}
170+
}
138171
}

0 commit comments

Comments
 (0)