Skip to content

Commit 6ebdc9e

Browse files
Support logpoint feature for java debugger (#184)
* Support logpoint feature for java debugger Signed-off-by: Jinbo Wang <[email protected]> * Refactor the code per review comments Signed-off-by: Jinbo Wang <[email protected]>
1 parent a1ff950 commit 6ebdc9e

File tree

13 files changed

+265
-100
lines changed

13 files changed

+265
-100
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class Breakpoint implements IBreakpoint {
3636
private int lineNumber = 0;
3737
private int hitCount = 0;
3838
private String condition = null;
39+
private String logMessage = null;
3940
private HashMap<Object, Object> propertyMap = new HashMap<>();
4041

4142
Breakpoint(VirtualMachine vm, IEventHub eventHub, String className, int lineNumber) {
@@ -55,6 +56,11 @@ public class Breakpoint implements IBreakpoint {
5556
this.condition = condition;
5657
}
5758

59+
Breakpoint(VirtualMachine vm, IEventHub eventHub, String className, int lineNumber, int hitCount, String condition, String logMessage) {
60+
this(vm, eventHub, className, lineNumber, hitCount, condition);
61+
this.logMessage = logMessage;
62+
}
63+
5864
// IDebugResource
5965
private List<EventRequest> requests = new ArrayList<>();
6066
private List<Disposable> subscriptions = new ArrayList<>();
@@ -132,6 +138,16 @@ public void setCondition(String condition) {
132138
this.condition = condition;
133139
}
134140

141+
@Override
142+
public void setLogMessage(String logMessage) {
143+
this.logMessage = logMessage;
144+
}
145+
146+
@Override
147+
public String getLogMessage() {
148+
return this.logMessage;
149+
}
150+
135151
@Override
136152
public CompletableFuture<IBreakpoint> install() {
137153
// It's possible that different class loaders create new class with the same name.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ public void terminate() {
7777
}
7878

7979
@Override
80-
public IBreakpoint createBreakpoint(String className, int lineNumber, int hitCount, String condition) {
81-
return new Breakpoint(vm, this.getEventHub(), className, lineNumber, hitCount, condition);
80+
public IBreakpoint createBreakpoint(String className, int lineNumber, int hitCount, String condition, String logMessage) {
81+
return new EvaluatableBreakpoint(vm, this.getEventHub(), className, lineNumber, hitCount, condition, logMessage);
8282
}
8383

8484

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 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 org.apache.commons.lang3.StringUtils;
15+
16+
import com.sun.jdi.VirtualMachine;
17+
18+
public class EvaluatableBreakpoint extends Breakpoint implements IEvaluatableBreakpoint {
19+
private Object compiledConditionalExpression = null;
20+
private Object compiledLogpointExpression = null;
21+
22+
EvaluatableBreakpoint(VirtualMachine vm, IEventHub eventHub, String className, int lineNumber) {
23+
super(vm, eventHub, className, lineNumber, 0, null);
24+
}
25+
26+
EvaluatableBreakpoint(VirtualMachine vm, IEventHub eventHub, String className, int lineNumber, int hitCount) {
27+
super(vm, eventHub, className, lineNumber, hitCount, null);
28+
}
29+
30+
EvaluatableBreakpoint(VirtualMachine vm, IEventHub eventHub, String className, int lineNumber, int hitCount, String condition) {
31+
super(vm, eventHub, className, lineNumber, hitCount, condition);
32+
}
33+
34+
EvaluatableBreakpoint(VirtualMachine vm, IEventHub eventHub, String className, int lineNumber, int hitCount, String condition, String logMessage) {
35+
super(vm, eventHub, className, lineNumber, hitCount, condition, logMessage);
36+
}
37+
38+
@Override
39+
public boolean containsEvaluatableExpression() {
40+
return containsConditionalExpression() || containsLogpointExpression();
41+
}
42+
43+
@Override
44+
public boolean containsConditionalExpression() {
45+
return StringUtils.isNotBlank(getCondition());
46+
}
47+
48+
@Override
49+
public boolean containsLogpointExpression() {
50+
return StringUtils.isNotBlank(getLogMessage());
51+
}
52+
53+
@Override
54+
public void setCompiledConditionalExpression(Object compiledExpression) {
55+
this.compiledConditionalExpression = compiledExpression;
56+
}
57+
58+
@Override
59+
public Object getCompiledConditionalExpression() {
60+
return compiledConditionalExpression;
61+
}
62+
63+
@Override
64+
public void setCompiledLogpointExpression(Object compiledExpression) {
65+
this.compiledLogpointExpression = compiledExpression;
66+
}
67+
68+
@Override
69+
public Object getCompiledLogpointExpression() {
70+
return compiledLogpointExpression;
71+
}
72+
73+
@Override
74+
public void setCondition(String condition) {
75+
super.setCondition(condition);
76+
setCompiledConditionalExpression(null);
77+
}
78+
79+
@Override
80+
public void setLogMessage(String logMessage) {
81+
super.setLogMessage(logMessage);
82+
setCompiledLogpointExpression(null);
83+
}
84+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ public interface IBreakpoint extends IDebugResource {
3131
String getCondition();
3232

3333
void setCondition(String condition);
34+
35+
String getLogMessage();
36+
37+
void setLogMessage(String logMessage);
3438
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public interface IDebugSession {
2828
void terminate();
2929

3030
// breakpoints
31-
IBreakpoint createBreakpoint(String className, int lineNumber, int hitCount, String condition);
31+
IBreakpoint createBreakpoint(String className, int lineNumber, int hitCount, String condition, String logMessage);
3232

3333
void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught);
3434

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 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+
public interface IEvaluatableBreakpoint extends IBreakpoint {
15+
boolean containsEvaluatableExpression();
16+
17+
boolean containsConditionalExpression();
18+
19+
boolean containsLogpointExpression();
20+
21+
void setCompiledConditionalExpression(Object compiledExpression);
22+
23+
Object getCompiledConditionalExpression();
24+
25+
void setCompiledLogpointExpression(Object compiledExpression);
26+
27+
Object getCompiledLogpointExpression();
28+
}

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

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ public class BreakpointManager {
3131
private List<IBreakpoint> breakpoints;
3232
private HashMap<String, HashMap<String, IBreakpoint>> sourceToBreakpoints;
3333
private AtomicInteger nextBreakpointId = new AtomicInteger(1);
34-
// BreakpointManager is the owner class of the breakpoint to compiled expression map, it will remove
35-
// the breakpoint from this map if the breakpoint is removed or its condition is changed
36-
private Map<IBreakpoint, Object> breakpointExpressionMap = new HashMap<>();
3734

3835
/**
3936
* Constructor.
@@ -80,7 +77,6 @@ public IBreakpoint[] setBreakpoints(String source, IBreakpoint[] breakpoints, bo
8077
} catch (Exception e) {
8178
logger.log(Level.SEVERE, String.format("Remove breakpoint exception: %s", e.toString()), e);
8279
}
83-
breakpointExpressionMap.remove(bp);
8480
this.breakpoints.remove(bp);
8581
}
8682
this.sourceToBreakpoints.put(source, null);
@@ -147,7 +143,6 @@ private void removeBreakpointsInternally(String source, IBreakpoint[] breakpoint
147143
// Destroy the breakpoint on the debugee VM.
148144
breakpoint.close();
149145
this.breakpoints.remove(breakpoint);
150-
breakpointExpressionMap.remove(breakpoint);
151146
breakpointMap.remove(String.valueOf(breakpoint.getLineNumber()));
152147
} catch (Exception e) {
153148
logger.log(Level.SEVERE, String.format("Remove breakpoint exception: %s", e.toString()), e);
@@ -171,28 +166,6 @@ public IBreakpoint[] getBreakpoints(String source) {
171166
return breakpointMap.values().toArray(new IBreakpoint[0]);
172167
}
173168

174-
175-
/**
176-
* Get the compiled expression map with breakpoint, it will be used in JdtEvaluationProvider#evaluateForBreakpoint for storing
177-
* the compiled expression when the first time this conditional breakpoint is hit.
178-
*
179-
* @return the compiled expression map
180-
*/
181-
public Map<IBreakpoint, Object> getBreakpointExpressionMap() {
182-
return breakpointExpressionMap;
183-
}
184-
185-
/**
186-
* Update the condition for the specified breakpoint, and clear the compiled expression for the breakpoint.
187-
*
188-
* @param breakpoint the conditional breakpoint
189-
* @param newCondition the new condition to be used.
190-
*/
191-
public void updateConditionCompiledExpression(IBreakpoint breakpoint, String newCondition) {
192-
breakpoint.setCondition(newCondition);
193-
breakpointExpressionMap.remove(breakpoint);
194-
}
195-
196169
/**
197170
* Cleanup all breakpoints and reset the breakpoint id counter.
198171
*/

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111

1212
package com.microsoft.java.debug.core.adapter;
1313

14-
import java.util.Map;
1514
import java.util.concurrent.CompletableFuture;
1615

17-
import com.microsoft.java.debug.core.IBreakpoint;
16+
import com.microsoft.java.debug.core.IEvaluatableBreakpoint;
1817
import com.sun.jdi.ThreadReference;
1918
import com.sun.jdi.Value;
2019

@@ -43,18 +42,14 @@ public interface IEvaluationProvider extends IProvider {
4342
CompletableFuture<Value> evaluate(String expression, ThreadReference thread, int depth);
4443

4544
/**
46-
* Evaluate the conditional breakpoint at the given thread and return the promise which is to be resolved/rejected when
47-
* the evaluation finishes. The breakpointExpressionMap value should be managed by this IEvaluationProvider, avoid duplicate compilation
48-
* on the same query when the conditional breakpoint is set inside a large loop, when the breakpoint is removed or the condition is changed,
49-
* the external owner of breakpointExpressionMap must remove the related map entry.
45+
* Evaluate the conditional breakpoint or logpoint at the given thread and return the promise which is to be resolved/rejected when
46+
* the evaluation finishes.
5047
*
51-
* @param breakpoint The conditional breakpoint
48+
* @param breakpoint The evaluatable breakpoint
5249
* @param thread The jdi thread to the expression will be executed at
53-
* @param breakpointExpressionMap The map has breakpoint as the key and the compiled expression object for next evaluation use.
5450
* @return the evaluation result future
5551
*/
56-
CompletableFuture<Value> evaluateForBreakpoint(IBreakpoint breakpoint, ThreadReference thread, Map<IBreakpoint, Object> breakpointExpressionMap);
57-
52+
CompletableFuture<Value> evaluateForBreakpoint(IEvaluatableBreakpoint breakpoint, ThreadReference thread);
5853

5954
/**
6055
* Call this method when the thread is to be resumed by user, it will first cancel ongoing evaluation tasks on specified thread and

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public CompletableFuture<Messages.Response> handle(Requests.Command command, Req
5252
caps.supportTerminateDebuggee = true;
5353
caps.supportsCompletionsRequest = true;
5454
caps.supportsRestartFrame = true;
55+
caps.supportsLogPoints = true;
5556
Types.ExceptionBreakpointFilter[] exceptionFilters = {
5657
Types.ExceptionBreakpointFilter.UNCAUGHT_EXCEPTION_FILTER,
5758
Types.ExceptionBreakpointFilter.CAUGHT_EXCEPTION_FILTER,

0 commit comments

Comments
 (0)