Skip to content

Commit cb2f8b3

Browse files
committed
Check target super-class implements FieldBackedContextAccessor before delegating to it
This avoids the need to create (and catch) `NoSuchMethodError`s when we fail to inject the super-class. For example starting the profiler before byte-buddy can trigger loading of various JDK concurrent classes that we would usually inject context into.
1 parent ae1c4c9 commit cb2f8b3

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/context/FieldBackedContextInjector.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,14 @@ public final class FieldBackedContextInjector implements AsmVisitorWrapper {
6060
Type.getMethodDescriptor(
6161
Type.VOID_TYPE, Type.getType(Object.class), Type.INT_TYPE, Type.getType(Object.class));
6262

63+
static final String IS_ASSIGNABLE_FROM_METHOD = "isAssignableFrom";
64+
static final String IS_ASSIGNABLE_FROM_METHOD_DESCRIPTOR =
65+
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Class.class));
66+
6367
static final String OBJECT_DESCRIPTOR = Type.getDescriptor(Object.class);
6468

65-
static final String LINKAGE_ERROR_CLASS = getInternalName(LinkageError.class.getName());
69+
public static final Type EXPECTED_SUPER_STORE_TYPE =
70+
Type.getType(FieldBackedContextAccessor.class);
6671

6772
/** Keeps track of injection requests for the class being transformed by the current thread. */
6873
static final ThreadLocal<BitSet> INJECTED_STORE_IDS = new ThreadLocal<>();
@@ -293,15 +298,25 @@ private void addStoreGetter(
293298
Label superStoreLabel = new Label();
294299
Label defaultStoreLabel = new Label();
295300

296-
mv.visitTryCatchBlock(
297-
superStoreLabel, defaultStoreLabel, defaultStoreLabel, LINKAGE_ERROR_CLASS);
301+
String superName = instrumentedType.getSuperClass().asErasure().getInternalName();
302+
303+
mv.visitLdcInsn(EXPECTED_SUPER_STORE_TYPE);
304+
mv.visitLdcInsn(Type.getObjectType(superName));
305+
mv.visitMethodInsn(
306+
Opcodes.INVOKEVIRTUAL,
307+
"java/lang/Class",
308+
IS_ASSIGNABLE_FROM_METHOD,
309+
IS_ASSIGNABLE_FROM_METHOD_DESCRIPTOR,
310+
false);
311+
mv.visitJumpInsn(Opcodes.IFEQ, defaultStoreLabel);
312+
298313
beginNextStore(mv, superStoreLabel);
299314

300-
invokeSuperGet(mv, instrumentedType.getSuperClass().asErasure().getInternalName());
315+
invokeSuperGet(mv, superName);
301316

302317
mv.visitLabel(defaultStoreLabel);
303318
if (frames) {
304-
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {LINKAGE_ERROR_CLASS});
319+
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
305320
}
306321

307322
invokeWeakGet(mv);
@@ -358,15 +373,25 @@ private void addStorePutter(
358373
Label superStoreLabel = new Label();
359374
Label defaultStoreLabel = new Label();
360375

361-
mv.visitTryCatchBlock(
362-
superStoreLabel, defaultStoreLabel, defaultStoreLabel, LINKAGE_ERROR_CLASS);
376+
String superName = instrumentedType.getSuperClass().asErasure().getInternalName();
377+
378+
mv.visitLdcInsn(EXPECTED_SUPER_STORE_TYPE);
379+
mv.visitLdcInsn(Type.getObjectType(superName));
380+
mv.visitMethodInsn(
381+
Opcodes.INVOKEVIRTUAL,
382+
"java/lang/Class",
383+
IS_ASSIGNABLE_FROM_METHOD,
384+
IS_ASSIGNABLE_FROM_METHOD_DESCRIPTOR,
385+
false);
386+
mv.visitJumpInsn(Opcodes.IFEQ, defaultStoreLabel);
387+
363388
beginNextStore(mv, superStoreLabel);
364389

365-
invokeSuperPut(mv, instrumentedType.getSuperClass().asErasure().getInternalName());
390+
invokeSuperPut(mv, superName);
366391

367392
mv.visitLabel(defaultStoreLabel);
368393
if (frames) {
369-
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {LINKAGE_ERROR_CLASS});
394+
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
370395
}
371396

372397
invokeWeakPut(mv);

0 commit comments

Comments
 (0)