Skip to content

Commit fe4bee2

Browse files
committed
Ensure shaded helpers have unique names when injected into class-loaders
1 parent ede74e3 commit fe4bee2

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

dd-java-agent/agent-builder/src/main/java/datadog/trace/agent/tooling/CombiningTransformerBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private void prepareInstrumentation(InstrumenterModule module, int instrumentati
119119
new FieldBackedContextRequestRewriter(contextStore, module.name()))
120120
: null;
121121

122-
adviceShader = AdviceShader.with(module.adviceShading());
122+
adviceShader = AdviceShader.with(module);
123123

124124
String[] helperClassNames = module.helperClassNames();
125125
if (module.injectHelperDependencies()) {

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AdviceShader.java

+42-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package datadog.trace.agent.tooling;
22

3+
import static java.util.Arrays.asList;
4+
import static java.util.Collections.emptyList;
5+
36
import datadog.trace.api.cache.DDCache;
47
import datadog.trace.api.cache.DDCaches;
8+
import java.util.HashMap;
9+
import java.util.List;
510
import java.util.Map;
611
import net.bytebuddy.jar.asm.ClassReader;
712
import net.bytebuddy.jar.asm.ClassVisitor;
@@ -12,18 +17,34 @@
1217
/** Shades advice bytecode by applying relocations to all references. */
1318
public final class AdviceShader {
1419
private final Map<String, String> relocations;
20+
private final List<String> helperNames;
1521

1622
private volatile Remapper remapper;
1723

24+
/**
25+
* Used when installing {@link InstrumenterModule}s. Ensures any injected helpers have unique
26+
* names so the original and relocated modules can inject helpers into the same class-loader.
27+
*/
28+
public static AdviceShader with(InstrumenterModule module) {
29+
if (module.adviceShading() != null) {
30+
return new AdviceShader(module.adviceShading(), asList(module.helperClassNames()));
31+
}
32+
return null;
33+
}
34+
35+
/**
36+
* Used to generate and check muzzle references. Only applies relocations declared in modules.
37+
*/
1838
public static AdviceShader with(Map<String, String> relocations) {
1939
if (relocations != null) {
20-
return new AdviceShader(relocations);
40+
return new AdviceShader(relocations, emptyList());
2141
}
2242
return null;
2343
}
2444

25-
private AdviceShader(Map<String, String> relocations) {
45+
private AdviceShader(Map<String, String> relocations, List<String> helperNames) {
2646
this.relocations = relocations;
47+
this.helperNames = helperNames;
2748
}
2849

2950
/** Applies shading before calling the given {@link ClassVisitor}. */
@@ -42,13 +63,28 @@ public byte[] shadeClass(byte[] bytecode) {
4263
return cw.toByteArray();
4364
}
4465

66+
/** Generates a unique shaded name for the given helper. */
67+
public String uniqueHelper(String dottedName) {
68+
int packageEnd = dottedName.lastIndexOf('.');
69+
if (packageEnd > 0) {
70+
return dottedName.substring(0, packageEnd + 1) + "shaded" + dottedName.substring(packageEnd);
71+
}
72+
return dottedName;
73+
}
74+
4575
final class AdviceMapper extends Remapper {
4676
private final DDCache<String, String> mappingCache = DDCaches.newFixedSizeCache(64);
4777

4878
/** Flattened sequence of old-prefix, new-prefix relocations. */
4979
private final String[] prefixes;
5080

81+
private final Map<String, String> helperMapping;
82+
5183
AdviceMapper() {
84+
this.helperMapping = new HashMap<>(helperNames.size() + 1, 1f);
85+
for (String h : helperNames) {
86+
this.helperMapping.put(h.replace('.', '/'), uniqueHelper(h).replace('.', '/'));
87+
}
5288
// convert relocations to a flattened sequence: old-prefix, new-prefix, etc.
5389
this.prefixes = new String[relocations.size() * 2];
5490
int i = 0;
@@ -68,6 +104,10 @@ final class AdviceMapper extends Remapper {
68104

69105
@Override
70106
public String map(String internalName) {
107+
String uniqueName = helperMapping.get(internalName);
108+
if (uniqueName != null) {
109+
return uniqueName;
110+
}
71111
if (internalName.startsWith("java/")
72112
|| internalName.startsWith("datadog/")
73113
|| internalName.startsWith("net/bytebuddy/")) {

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/HelperInjector.java

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ private Map<String, byte[]> getHelperMap() throws IOException {
9393
byte[] classBytes = classFileLocator.locate(helperName).resolve();
9494
if (adviceShader != null) {
9595
classBytes = adviceShader.shadeClass(classBytes);
96+
helperName = adviceShader.uniqueHelper(helperName);
9697
}
9798
classnameToBytes.put(helperName, classBytes);
9899
}

0 commit comments

Comments
 (0)