Skip to content

Commit c06c54a

Browse files
authored
Remove static inherited fields collection (#8832)
To avoid premature class loading and potential LinkageError we are not collecting the static inherited fields of a class
1 parent 6a77487 commit c06c54a

File tree

2 files changed

+6
-69
lines changed

2 files changed

+6
-69
lines changed

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.datadog.debugger.instrumentation;
22

3-
import static com.datadog.debugger.instrumentation.ASMHelper.extractSuperClass;
43
import static com.datadog.debugger.instrumentation.ASMHelper.getStatic;
54
import static com.datadog.debugger.instrumentation.ASMHelper.invokeConstructor;
65
import static com.datadog.debugger.instrumentation.ASMHelper.invokeStatic;
@@ -1136,51 +1135,13 @@ private static List<FieldNode> extractStaticFields(
11361135
}
11371136
}
11381137
}
1139-
if (!Config.get().isDynamicInstrumentationInstrumentTheWorld()) {
1140-
// Collects inherited static fields only if the ITW mode is not enabled
1141-
// because it can lead to LinkageError: attempted duplicate class definition
1142-
// for example, when a probe is located in method overridden in enum element
1143-
addInheritedStaticFields(classNode, classLoader, limits, results, fieldCount);
1144-
}
1138+
// Collecting inherited static fields is problematic because it some cases can lead to
1139+
// LinkageError: attempted duplicate class definition
1140+
// as we force to load a class to get the static fields in a different order than the JVM
1141+
// for example, when a probe is located in method overridden in enum element
11451142
return results;
11461143
}
11471144

1148-
private static void addInheritedStaticFields(
1149-
ClassNode classNode,
1150-
ClassLoader classLoader,
1151-
Limits limits,
1152-
List<FieldNode> results,
1153-
int fieldCount) {
1154-
String superClassName = extractSuperClass(classNode);
1155-
while (!superClassName.equals(Object.class.getTypeName())) {
1156-
Class<?> clazz;
1157-
try {
1158-
clazz = Class.forName(superClassName, false, classLoader);
1159-
} catch (ClassNotFoundException ex) {
1160-
break;
1161-
}
1162-
try {
1163-
for (Field field : clazz.getDeclaredFields()) {
1164-
if (isStaticField(field) && !isFinalField(field)) {
1165-
String desc = Type.getDescriptor(field.getType());
1166-
FieldNode fieldNode =
1167-
new FieldNode(field.getModifiers(), field.getName(), desc, null, field);
1168-
results.add(fieldNode);
1169-
LOGGER.debug("Adding static inherited field {}", fieldNode.name);
1170-
fieldCount++;
1171-
if (fieldCount > limits.maxFieldCount) {
1172-
return;
1173-
}
1174-
}
1175-
}
1176-
} catch (ClassCircularityError ex) {
1177-
break;
1178-
}
1179-
clazz = clazz.getSuperclass();
1180-
superClassName = clazz.getTypeName();
1181-
}
1182-
}
1183-
11841145
private int declareContextVar(InsnList insnList) {
11851146
int var = newVar(CAPTURED_CONTEXT_TYPE);
11861147
getStatic(insnList, CAPTURED_CONTEXT_TYPE, "EMPTY_CAPTURING_CONTEXT");

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -939,27 +939,6 @@ public void fieldExtractorNotAccessible() throws IOException, URISyntaxException
939939
"Field is not accessible: module java.base does not opens/exports to the current module");
940940
}
941941

942-
@Test
943-
@EnabledForJreRange(min = JRE.JAVA_17)
944-
public void staticFieldExtractorNotAccessible() throws IOException, URISyntaxException {
945-
final String CLASS_NAME = "com.datadog.debugger.CapturedSnapshot30";
946-
LogProbe logProbe =
947-
createMethodProbe(PROBE_ID, CLASS_NAME + "$MyHttpURLConnection", "process", "()");
948-
TestSnapshotListener listener = installProbes(logProbe);
949-
Class<?> testClass = compileAndLoadClass(CLASS_NAME);
950-
int result = Reflect.onClass(testClass).call("main", "static").get();
951-
assertEquals(42, result);
952-
Snapshot snapshot = assertOneSnapshot(listener);
953-
assertCaptureStaticFieldsNotCaptured(
954-
snapshot.getCaptures().getReturn(),
955-
"followRedirects",
956-
"Field is not accessible: module java.base does not opens/exports to the current module");
957-
assertCaptureStaticFieldsNotCaptured(
958-
snapshot.getCaptures().getReturn(),
959-
"factory",
960-
"Field is not accessible: module java.base does not opens/exports to the current module");
961-
}
962-
963942
@Test
964943
public void uncaughtException() throws IOException, URISyntaxException {
965944
final String CLASS_NAME = "CapturedSnapshot05";
@@ -1611,12 +1590,9 @@ public void staticInheritedFields() throws IOException, URISyntaxException {
16111590
Snapshot snapshot = assertOneSnapshot(listener);
16121591
Map<String, CapturedContext.CapturedValue> staticFields =
16131592
snapshot.getCaptures().getReturn().getStaticFields();
1614-
assertEquals(7, staticFields.size());
1593+
// inherited static fields are not collected
1594+
assertEquals(2, staticFields.size());
16151595
assertEquals("barfoo", MoshiSnapshotTestHelper.getValue(staticFields.get("strValue")));
1616-
assertEquals("48", MoshiSnapshotTestHelper.getValue(staticFields.get("intValue")));
1617-
assertEquals("6.28", MoshiSnapshotTestHelper.getValue(staticFields.get("doubleValue")));
1618-
assertEquals("[1, 2, 3, 4]", MoshiSnapshotTestHelper.getValue(staticFields.get("longValues")));
1619-
assertEquals("[foo, bar]", MoshiSnapshotTestHelper.getValue(staticFields.get("strValues")));
16201596
}
16211597

16221598
@Test

0 commit comments

Comments
 (0)