Skip to content

Commit b19886f

Browse files
author
daguimu
committed
fix: prevent StackOverflowError in ObjectView JSON mode for circular references
When watch command uses JSON format (options json true), fastjson2 serialization can enter infinite recursion on objects with circular references or deeply nested object graphs, causing StackOverflowError. Fix by adding JSONWriter.Feature.ReferenceDetection to detect and break circular references using JSON $ref syntax, and catch StackOverflowError as a safety net with a user-friendly error message. Fixes #3095
1 parent 9e56f55 commit b19886f

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

core/src/main/java/com/taobao/arthas/core/view/ObjectView.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,20 @@ protected void setDefaultValue(List<FieldWriter> fieldWriters, Class objectClass
3838
});
3939

4040
public static String toJsonString(Object object) {
41-
JSONWriter.Context context = new JSONWriter.Context(JSON_OBJECT_WRITER_PROVIDER);
42-
context.setMaxLevel(4097);
43-
context.config(JSONWriter.Feature.IgnoreErrorGetter,
44-
JSONWriter.Feature.ReferenceDetection,
45-
JSONWriter.Feature.IgnoreNonFieldGetter,
46-
JSONWriter.Feature.WriteNonStringKeyAsString);
47-
return JSON.toJSONString(object, context);
41+
try {
42+
JSONWriter.Context context = new JSONWriter.Context(JSON_OBJECT_WRITER_PROVIDER);
43+
context.setMaxLevel(4097);
44+
context.config(JSONWriter.Feature.IgnoreErrorGetter,
45+
JSONWriter.Feature.ReferenceDetection,
46+
JSONWriter.Feature.IgnoreNonFieldGetter,
47+
JSONWriter.Feature.WriteNonStringKeyAsString);
48+
return JSON.toJSONString(object, context);
49+
} catch (StackOverflowError e) {
50+
logger.error("ObjectView JSON serialization stackoverflow, object class: {}", object == null ? "null" : object.getClass(), e);
51+
return "ERROR DATA!!! object class: " + (object == null ? "null" : object.getClass())
52+
+ ", StackOverflowError: circular reference or object graph too deep. "
53+
+ "Try disabling json mode: options json false";
54+
}
4855
}
4956

5057
private final Object object;

core/src/test/java/com/taobao/arthas/core/view/ObjectViewTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,4 +393,27 @@ public static JsonFormatSingleton getInstance() {
393393
return INSTANCE;
394394
}
395395
}
396+
397+
@Test
398+
public void testJsonModeCircularReference() {
399+
GlobalOptions.isUsingJson = true;
400+
try {
401+
CircularRef a = new CircularRef("a");
402+
CircularRef b = new CircularRef("b");
403+
a.ref = b;
404+
b.ref = a;
405+
ObjectView objectView = new ObjectView(a, 3);
406+
String result = objectView.draw();
407+
// Should not throw StackOverflowError
408+
Assert.assertNotNull(result);
409+
} finally {
410+
GlobalOptions.isUsingJson = false;
411+
}
412+
}
413+
414+
private static class CircularRef {
415+
String name;
416+
CircularRef ref;
417+
CircularRef(String name) { this.name = name; }
418+
}
396419
}

0 commit comments

Comments
 (0)