Skip to content

Commit 160360d

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 2a8627d commit 160360d

File tree

1 file changed

+38
-21
lines changed

1 file changed

+38
-21
lines changed

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

Lines changed: 38 additions & 21 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<>();
@@ -290,19 +295,25 @@ private void addStoreGetter(
290295

291296
// else... delegate to superclass - but be prepared to fall back to weak-map
292297
if (hasMoreStores) {
293-
Label superStoreLabel = new Label();
294-
Label defaultStoreLabel = new Label();
298+
Label fallbackStoreLabel = new Label();
295299

296-
mv.visitTryCatchBlock(
297-
superStoreLabel, defaultStoreLabel, defaultStoreLabel, LINKAGE_ERROR_CLASS);
298-
beginNextStore(mv, superStoreLabel);
300+
String superName = instrumentedType.getSuperClass().asErasure().getInternalName();
299301

300-
invokeSuperGet(mv, instrumentedType.getSuperClass().asErasure().getInternalName());
302+
// check superclass has expected type before calling
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, fallbackStoreLabel);
301312

302-
mv.visitLabel(defaultStoreLabel);
303-
if (frames) {
304-
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {LINKAGE_ERROR_CLASS});
305-
}
313+
invokeSuperGet(mv, superName);
314+
315+
// else use weak-map fallback
316+
beginNextStore(mv, fallbackStoreLabel);
306317

307318
invokeWeakGet(mv);
308319
}
@@ -355,19 +366,25 @@ private void addStorePutter(
355366

356367
// else... delegate to superclass - but be prepared to fall back to weak-map
357368
if (hasMoreStores) {
358-
Label superStoreLabel = new Label();
359-
Label defaultStoreLabel = new Label();
369+
Label fallbackStoreLabel = new Label();
360370

361-
mv.visitTryCatchBlock(
362-
superStoreLabel, defaultStoreLabel, defaultStoreLabel, LINKAGE_ERROR_CLASS);
363-
beginNextStore(mv, superStoreLabel);
371+
String superName = instrumentedType.getSuperClass().asErasure().getInternalName();
364372

365-
invokeSuperPut(mv, instrumentedType.getSuperClass().asErasure().getInternalName());
373+
// check superclass has expected type before calling
374+
mv.visitLdcInsn(EXPECTED_SUPER_STORE_TYPE);
375+
mv.visitLdcInsn(Type.getObjectType(superName));
376+
mv.visitMethodInsn(
377+
Opcodes.INVOKEVIRTUAL,
378+
"java/lang/Class",
379+
IS_ASSIGNABLE_FROM_METHOD,
380+
IS_ASSIGNABLE_FROM_METHOD_DESCRIPTOR,
381+
false);
382+
mv.visitJumpInsn(Opcodes.IFEQ, fallbackStoreLabel);
366383

367-
mv.visitLabel(defaultStoreLabel);
368-
if (frames) {
369-
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {LINKAGE_ERROR_CLASS});
370-
}
384+
invokeSuperPut(mv, superName);
385+
386+
// else use weak-map fallback
387+
beginNextStore(mv, fallbackStoreLabel);
371388

372389
invokeWeakPut(mv);
373390
}

0 commit comments

Comments
 (0)