1
1
package datadog .trace .instrumentation .jetty9 ;
2
2
3
- import static java .lang .Math .max ;
4
3
import static net .bytebuddy .jar .asm .Opcodes .ALOAD ;
5
4
import static net .bytebuddy .jar .asm .Opcodes .ASTORE ;
6
- import static net .bytebuddy .jar .asm .Opcodes .DUP ;
7
5
import static net .bytebuddy .jar .asm .Opcodes .F_SAME ;
8
6
import static net .bytebuddy .jar .asm .Opcodes .GOTO ;
9
7
import static net .bytebuddy .jar .asm .Opcodes .H_INVOKESTATIC ;
8
+ import static net .bytebuddy .jar .asm .Opcodes .IFNE ;
9
+ import static net .bytebuddy .jar .asm .Opcodes .INVOKESTATIC ;
10
+ import static net .bytebuddy .jar .asm .Opcodes .INVOKEVIRTUAL ;
10
11
11
12
import datadog .context .Context ;
12
13
import datadog .trace .api .gateway .Flow ;
13
14
import datadog .trace .bootstrap .instrumentation .api .AgentSpan ;
15
+ import datadog .trace .bootstrap .instrumentation .api .Java8BytecodeBridge ;
14
16
import datadog .trace .instrumentation .jetty .JettyBlockingHelper ;
15
17
import java .io .BufferedWriter ;
16
18
import java .io .FileOutputStream ;
30
32
* Instruments the handle (or run) method to put the calls to <code>getServer().handle(this)</code>
31
33
* under a condition, for the {@link org.eclipse.jetty.server.HttpChannel} class.
32
34
*
33
- * <p>In particular, for earlier versions of jetty: <code>
35
+ * <p>In particular, for earlier versions of jetty:
36
+ * <pre>
34
37
* case REQUEST_DISPATCH:
35
38
* // ...
36
39
* getServer().handle(this);
37
- * </code> is replaced with: <code>
40
+ * </pre>
41
+ * is replaced with:
42
+ * <pre>
38
43
* case REQUEST_DISPATCH:
39
44
* // ...
40
- * if (JettyBlockingHelper.block(this.getRequest(), this.getResponse(), context )) {
45
+ * if (JettyBlockingHelper.block(this.getRequest(), this.getResponse(), Java8BytecodeBridge.getCurrentContext() )) {
41
46
* // nothing
42
47
* } else {
43
48
* getServer().handle(this);
44
49
* }
45
- * </code> And for later versions of Jetty before 11.16.0, <code>
50
+ * </pre>
51
+ * And for later versions of Jetty before 11.16.0,
52
+ * <pre>
46
53
* case DISPATCH:
47
54
* {
48
55
* // ...
51
58
* // ...
52
59
* getServer().handle(HttpChannel.this);
53
60
* });
54
- * </code> is replaced with: <code>
61
+ * </pre>
62
+ * is replaced with:
63
+ * <pre>
55
64
* case DISPATCH:
56
65
* {
57
66
* // ...
68
77
* getServer().handle(HttpChannel.this);
69
78
* });
70
79
* }
71
- * </code> And for later versions of Jetty, <code>
80
+ * </pre>
81
+ * And for later versions of Jetty,
82
+ * <pre>
72
83
* case DISPATCH:
73
84
* {
74
85
* // ...
75
86
* dispatch(DispatcherType.REQUEST, _requestDispatcher);
76
- * </code> is replaced with: <code>
87
+ * </pre>
88
+ * is replaced with:
89
+ * <pre>
77
90
* case DISPATCH:
78
91
* {
79
92
* // ...
87
100
* } else {
88
101
* dispatch(DispatcherType.REQUEST, _requestDispatcher);
89
102
* }
90
- * </code >
103
+ * </pre >
91
104
*/
92
105
public class HandleVisitor extends MethodVisitor {
93
106
private static final Logger log = LoggerFactory .getLogger (HandleVisitor .class );
94
- private static final int CONTEXT_VAR = 100 ;
107
+ private static final int CONTEXT_VAR = 1000 ;
95
108
96
109
/** Whether the next store is supposed to store the Context variable. */
97
110
private boolean lookForStore ;
98
111
/** Whether the Context variable was stored to local index {@link #CONTEXT_VAR}. */
99
112
private boolean contextStored ;
113
+ // private int contextVarIndex = -1;
100
114
/** Whether the handle() method injection was successful .*/
101
115
private boolean success ;
102
116
private final String methodName ;
@@ -129,13 +143,13 @@ DelayCertainInsMethodVisitor delayVisitorDelegate() {
129
143
return (DelayCertainInsMethodVisitor ) this .mv ;
130
144
}
131
145
132
- @ Override
133
- public void visitLocalVariable (String name , String descriptor , String signature , Label start , Label end , int index ) {
134
- if (contextStored && index == CONTEXT_VAR ) {
135
- super .visitLocalVariable ("context" , Type .getDescriptor (Context .class ), null , start , end , CONTEXT_VAR );
136
- }
137
- super .visitLocalVariable (name , descriptor , signature , start , end , index );
138
- }
146
+ // @Override
147
+ // public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
148
+ // if (contextStored && index == CONTEXT_VAR) {
149
+ // super.visitLocalVariable("context", Type.getDescriptor(Context.class), null, start, end, CONTEXT_VAR);
150
+ // }
151
+ // super.visitLocalVariable(name, descriptor, signature, start, end, index);
152
+ // }
139
153
140
154
@ Override
141
155
public void visitMethodInsn (
@@ -147,14 +161,14 @@ public void visitMethodInsn(
147
161
if (!contextStored ) {
148
162
lookForStore =
149
163
!lookForStore
150
- && opcode == Opcodes . INVOKEVIRTUAL
164
+ && opcode == INVOKEVIRTUAL
151
165
&& name .equals ("startSpan" )
152
166
&& descriptor .endsWith ("Ldatadog/context/Context;" );
153
167
if (lookForStore ) {
154
168
debug ("Found store" );
155
169
}
156
170
} else if (!success
157
- && opcode == Opcodes . INVOKEVIRTUAL
171
+ && opcode == INVOKEVIRTUAL
158
172
&& owner .equals ("org/eclipse/jetty/server/Server" )
159
173
&& name .equals ("handle" )
160
174
&& descriptor .equals ("(Lorg/eclipse/jetty/server/HttpChannel;)V" )) {
@@ -177,32 +191,42 @@ public void visitMethodInsn(
177
191
178
192
// Declare label to insert after Server.handle() call
179
193
Label afterHandle = new Label ();
180
- // Inject blocking helper call
194
+ // Inject blocking helper call and get its three parameters onto the stack:
195
+ // - Request
196
+ // - Response
197
+ // - Context -- retrieved from current as attached just earlier from tracing instrumentation
181
198
super .visitVarInsn (ALOAD , 0 );
182
199
super .visitMethodInsn (
183
- Opcodes . INVOKEVIRTUAL ,
200
+ INVOKEVIRTUAL ,
184
201
"org/eclipse/jetty/server/HttpChannel" ,
185
202
"getRequest" ,
186
203
"()Lorg/eclipse/jetty/server/Request;" ,
187
204
false );
188
205
super .visitVarInsn (ALOAD , 0 );
189
206
super .visitMethodInsn (
190
- Opcodes . INVOKEVIRTUAL ,
207
+ INVOKEVIRTUAL ,
191
208
"org/eclipse/jetty/server/HttpChannel" ,
192
209
"getResponse" ,
193
210
"()Lorg/eclipse/jetty/server/Response;" ,
194
211
false );
195
- super .visitVarInsn (ALOAD , CONTEXT_VAR );
196
212
super .visitMethodInsn (
197
- Opcodes .INVOKESTATIC ,
213
+ INVOKESTATIC ,
214
+ Type .getInternalName (Java8BytecodeBridge .class ),
215
+ "getCurrentContext" ,
216
+ "()Ldatadog/context/Context;" ,
217
+ false
218
+ );
219
+ // super.visitVarInsn(ALOAD, CONTEXT_VAR);
220
+ super .visitMethodInsn (
221
+ INVOKESTATIC ,
198
222
Type .getInternalName (JettyBlockingHelper .class ),
199
223
"block" ,
200
224
"(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;"
201
225
+ Type .getDescriptor (Context .class )
202
226
+ ")Z" ,
203
227
false );
204
228
// Inject jump to after Server.handle() call if blocked
205
- super .visitJumpInsn (Opcodes . IFNE , afterHandle );
229
+ super .visitJumpInsn (IFNE , afterHandle );
206
230
// Inject getServer() and Server.handle() calls
207
231
mv .commitVisitations (savedVisitations );
208
232
super .visitMethodInsn (opcode , owner , name , descriptor , isInterface );
@@ -213,7 +237,7 @@ public void visitMethodInsn(
213
237
this .success = true ;
214
238
return ;
215
239
} else if (!success
216
- && (opcode == Opcodes .INVOKESPECIAL || opcode == Opcodes . INVOKEVIRTUAL )
240
+ && (opcode == Opcodes .INVOKESPECIAL || opcode == INVOKEVIRTUAL )
217
241
&& owner .equals ("org/eclipse/jetty/server/HttpChannel" )
218
242
&& name .equals ("dispatch" )
219
243
&& (descriptor .equals (
@@ -265,14 +289,14 @@ public void visitMethodInsn(
265
289
// RequestBlockingAction, AgentSpan)
266
290
super .visitVarInsn (ALOAD , 0 );
267
291
super .visitMethodInsn (
268
- Opcodes . INVOKEVIRTUAL ,
292
+ INVOKEVIRTUAL ,
269
293
"org/eclipse/jetty/server/HttpChannel" ,
270
294
"getRequest" ,
271
295
"()Lorg/eclipse/jetty/server/Request;" ,
272
296
false );
273
297
super .visitVarInsn (ALOAD , 0 );
274
298
super .visitMethodInsn (
275
- Opcodes . INVOKEVIRTUAL ,
299
+ INVOKEVIRTUAL ,
276
300
"org/eclipse/jetty/server/HttpChannel" ,
277
301
"getResponse" ,
278
302
"()Lorg/eclipse/jetty/server/Response;" ,
@@ -369,18 +393,19 @@ public void visitVarInsn(int opcode, int varIndex) {
369
393
debug ("Found context" );
370
394
contextStored = true ;
371
395
lookForStore = false ;
396
+ // contextVarIndex = varIndex;
372
397
// Duplicate on stack and store to its own local var
373
- super .visitInsn (DUP );
374
- super .visitVarInsn (ASTORE , CONTEXT_VAR );
398
+ // super.visitInsn(DUP);
399
+ // super.visitVarInsn(ASTORE, CONTEXT_VAR);
375
400
}
376
401
super .visitVarInsn (opcode , varIndex );
377
402
}
378
403
379
- @ Override
380
- public void visitMaxs (int maxStack , int maxLocals ) {
381
- debug ("VisitMaxs stack: " + maxStack + ", locals: " + maxLocals );
382
- super .visitMaxs (maxStack , max (maxLocals , CONTEXT_VAR + 1 ));
383
- }
404
+ // @Override
405
+ // public void visitMaxs(int maxStack, int maxLocals) {
406
+ // debug("VisitMaxs stack: " + maxStack + ", locals: " + maxLocals);
407
+ // super.visitMaxs(maxStack, max(maxLocals, CONTEXT_VAR + 1));
408
+ // }
384
409
385
410
@ Override
386
411
public void visitEnd () {
0 commit comments