Skip to content

Commit 9a84e7c

Browse files
if listing the variable value of a large object throws OOM or timeout exception, just display its basic info (microsoft#385)
1 parent 64b54e8 commit 9a84e7c

File tree

2 files changed

+84
-28
lines changed

2 files changed

+84
-28
lines changed

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

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017-2020 Microsoft Corporation and others.
2+
* Copyright (c) 2017-2021 Microsoft Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -14,7 +14,6 @@
1414
import java.util.Arrays;
1515
import java.util.List;
1616
import java.util.Map;
17-
import java.util.concurrent.CancellationException;
1817
import java.util.concurrent.CompletableFuture;
1918
import java.util.concurrent.CompletionException;
2019
import java.util.concurrent.ExecutionException;
@@ -103,31 +102,58 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
103102
indexedVariables = ((IntegerValue) sizeValue).value();
104103
}
105104
}
106-
} catch (CancellationException | IllegalArgumentException | InterruptedException
107-
| ExecutionException | UnsupportedOperationException e) {
108-
logger.log(Level.INFO,
109-
String.format("Failed to get the logical size for the type %s.", value.type().name()), e);
105+
} catch (Exception e) {
106+
logger.log(Level.INFO, "Failed to get the logical size of the variable", e);
110107
}
111108
}
112109
int referenceId = 0;
113110
if (indexedVariables > 0 || (indexedVariables < 0 && value instanceof ObjectReference)) {
114111
referenceId = context.getRecyclableIdPool().addObject(threadId, varProxy);
115112
}
116113

117-
String valueString = variableFormatter.valueToString(value, options);
114+
boolean hasErrors = false;
115+
String valueString = null;
116+
try {
117+
valueString = variableFormatter.valueToString(value, options);
118+
} catch (OutOfMemoryError e) {
119+
hasErrors = true;
120+
logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e);
121+
valueString = "<Unable to display the value of a large object>";
122+
} catch (Exception e) {
123+
hasErrors = true;
124+
logger.log(Level.SEVERE, "Failed to resolve the variable value", e);
125+
valueString = "<Failed to resolve the variable value due to \"" + e.getMessage() + "\">";
126+
}
127+
118128
String detailsString = null;
119-
if (sizeValue != null) {
129+
if (hasErrors) {
130+
// If failed to resolve the variable value, skip the details info as well.
131+
} else if (sizeValue != null) {
120132
detailsString = "size=" + variableFormatter.valueToString(sizeValue, options);
121133
} else if (DebugSettings.getCurrent().showToString) {
122-
detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine);
134+
try {
135+
detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine);
136+
} catch (OutOfMemoryError e) {
137+
logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e);
138+
detailsString = "<Unable to display the details of a large object>";
139+
} catch (Exception e) {
140+
logger.log(Level.SEVERE, "Failed to compute the toString() value", e);
141+
detailsString = "<Failed to resolve the variable details due to \"" + e.getMessage() + "\">";
142+
}
123143
}
124144

125145
if ("clipboard".equals(evalArguments.context) && detailsString != null) {
126146
response.body = new Responses.EvaluateResponseBody(detailsString, -1, "String", 0);
127147
} else {
148+
String typeString = "";
149+
try {
150+
typeString = variableFormatter.typeToString(value == null ? null : value.type(), options);
151+
} catch (Exception e) {
152+
logger.log(Level.SEVERE, "Failed to resolve the variable type", e);
153+
typeString = "";
154+
}
128155
response.body = new Responses.EvaluateResponseBody((detailsString == null) ? valueString : valueString + " " + detailsString,
129-
referenceId, variableFormatter.typeToString(value == null ? null : value.type(), options),
130-
Math.max(indexedVariables, 0));
156+
referenceId, typeString, Math.max(indexedVariables, 0));
131157
}
132158
return response;
133159
}

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

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017-2020 Microsoft Corporation and others.
2+
* Copyright (c) 2017-2021 Microsoft Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -19,9 +19,7 @@
1919
import java.util.List;
2020
import java.util.Map;
2121
import java.util.Set;
22-
import java.util.concurrent.CancellationException;
2322
import java.util.concurrent.CompletableFuture;
24-
import java.util.concurrent.ExecutionException;
2523
import java.util.logging.Level;
2624
import java.util.logging.Logger;
2725
import java.util.stream.Collectors;
@@ -133,7 +131,12 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
133131
try {
134132
ObjectReference containerObj = (ObjectReference) containerNode.getProxiedVariable();
135133
if (DebugSettings.getCurrent().showLogicalStructure && evaluationEngine != null) {
136-
JavaLogicalStructure logicalStructure = JavaLogicalStructureManager.getLogicalStructure(containerObj);
134+
JavaLogicalStructure logicalStructure = null;
135+
try {
136+
logicalStructure = JavaLogicalStructureManager.getLogicalStructure(containerObj);
137+
} catch (Exception e) {
138+
logger.log(Level.WARNING, "Failed to get the logical structure for the variable, fall back to the Object view.", e);
139+
}
137140
if (isUnboundedTypeContainer && logicalStructure != null && containerEvaluateName != null) {
138141
containerEvaluateName = "((" + logicalStructure.getFullyQualifiedName() + ")" + containerEvaluateName + ")";
139142
isUnboundedTypeContainer = false;
@@ -162,11 +165,8 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
162165
childrenList.add(variable);
163166
}
164167
}
165-
} catch (IllegalArgumentException | CancellationException | InterruptedException | ExecutionException e) {
166-
logger.log(Level.WARNING,
167-
String.format("Failed to get the logical structure for the type %s, fall back to the Object view.",
168-
containerObj.type().name()),
169-
e);
168+
} catch (Exception e) {
169+
logger.log(Level.WARNING, "Failed to get the logical structure for the variable, fall back to the Object view.", e);
170170
}
171171

172172
logicalStructure = null;
@@ -241,9 +241,8 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
241241
indexedVariables = ((IntegerValue) sizeValue).value();
242242
}
243243
}
244-
} catch (CancellationException | IllegalArgumentException | InterruptedException | ExecutionException | UnsupportedOperationException e) {
245-
logger.log(Level.INFO,
246-
String.format("Failed to get the logical size for the type %s.", value.type().name()), e);
244+
} catch (Exception e) {
245+
logger.log(Level.INFO, "Failed to get the logical size of the variable", e);
247246
}
248247
}
249248

@@ -275,15 +274,46 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
275274
varProxy.setUnboundedType(javaVariable.isUnboundedType());
276275
}
277276

278-
Types.Variable typedVariables = new Types.Variable(name, variableFormatter.valueToString(value, options),
279-
variableFormatter.typeToString(value == null ? null : value.type(), options),
280-
referenceId, evaluateName);
277+
boolean hasErrors = false;
278+
String valueString = null;
279+
try {
280+
valueString = variableFormatter.valueToString(value, options);
281+
} catch (OutOfMemoryError e) {
282+
hasErrors = true;
283+
logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e);
284+
valueString = "<Unable to display the value of a large object>";
285+
} catch (Exception e) {
286+
hasErrors = true;
287+
logger.log(Level.SEVERE, "Failed to resolve the variable value", e);
288+
valueString = "<Failed to resolve the variable value due to \"" + e.getMessage() + "\">";
289+
}
290+
291+
String typeString = "";
292+
try {
293+
typeString = variableFormatter.typeToString(value == null ? null : value.type(), options);
294+
} catch (Exception e) {
295+
logger.log(Level.SEVERE, "Failed to resolve the variable type", e);
296+
typeString = "";
297+
}
298+
299+
Types.Variable typedVariables = new Types.Variable(name, valueString, typeString, referenceId, evaluateName);
281300
typedVariables.indexedVariables = Math.max(indexedVariables, 0);
301+
282302
String detailsValue = null;
283-
if (sizeValue != null) {
303+
if (hasErrors) {
304+
// If failed to resolve the variable value, skip the details info as well.
305+
} else if (sizeValue != null) {
284306
detailsValue = "size=" + variableFormatter.valueToString(sizeValue, options);
285307
} else if (DebugSettings.getCurrent().showToString) {
286-
detailsValue = VariableDetailUtils.formatDetailsValue(value, containerNode.getThread(), variableFormatter, options, evaluationEngine);
308+
try {
309+
detailsValue = VariableDetailUtils.formatDetailsValue(value, containerNode.getThread(), variableFormatter, options, evaluationEngine);
310+
} catch (OutOfMemoryError e) {
311+
logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e);
312+
detailsValue = "<Unable to display the details of a large object>";
313+
} catch (Exception e) {
314+
logger.log(Level.SEVERE, "Failed to compute the toString() value", e);
315+
detailsValue = "<Failed to resolve the variable details due to \"" + e.getMessage() + "\">";
316+
}
287317
}
288318

289319
if (detailsValue != null) {

0 commit comments

Comments
 (0)