Fix incorrect argument name for already traced methods#4630
Conversation
When instrumenting a method with a debugger probe that contains also tracer instrumentation (using @trace annotation or `trace.methods` property) argument names was not mapped correctly and p0, p1, appears in the snapshot. This is due to ByteBuddy transformation messing up the LocalVariableTable that helps to maps local vars with names. Args are also local vars and following the JVM spec, the first local vars must match the methods args. LocalVariableTable is optional and only used for debugger so it does not prevent the actual execution of the method. The fix consists to reassigned local var information to arg slot. Added smoke tests for this case.
shatzi
left a comment
There was a problem hiding this comment.
Awesome stuff JP.
Maybe worth creating a ticket of dealing with variables sharing slots as it would be different name depend on the location of the method.
| LocalVariableNode[] localVars = new LocalVariableNode[maxIndex + 1]; | ||
| localVarBaseOffset = sortedLocalVars.get(0).index; | ||
| for (LocalVariableNode localVariableNode : sortedLocalVars) { | ||
| localVars[localVariableNode.index] = localVariableNode; |
There was a problem hiding this comment.
what if multiple localVariables uses the same slot (I think you showed me an example for that)?
Maybe we should also look at the variable range so get variable name would be correct depend on the line (offset) we are instrumenting.
There was a problem hiding this comment.
To be clear the localVarBySlot address only the problematic of args. which does not share slot with other since they are scoped for the entire method.
It replaces the argumentNames field previously
for pure local vars see
and isInScope method:
There was a problem hiding this comment.
Awesome. thanks for clearing this out. looks good.
What Does This Do
The fix consists to reassigned local var information to arg slot.
Added smoke tests for this case.
Motivation
When instrumenting a method with a debugger probe that contains also tracer instrumentation (using @trace annotation or
trace.methodsproperty) argument names was not mapped correctly and p0, p1, appears in the snapshot.This is due to ByteBuddy transformation messing up the LocalVariableTable that helps to maps local vars with names. Args are also local vars and following the JVM spec, the first local vars must match the methods args.
LocalVariableTable is optional and only used for debugger so it does not prevent the actual execution of the method.
Additional Notes
Example with petclinic:
VetController.processWithArgmethod:When we start with -Ddd.trace.methods=org.springframework.samples.petclinic.vet.VetController[processWithArg]
This case works beside the JVM specification, because the slot 1 is still assigned to the parameter, instrumented bytcode do some dance with it to conform with the new
LocalVariableTable:Before calling the original code
System.out.println(obj)we load from slot 1 the actual parameter of the method (obj) into the stack and store it back into slot 4 to match the
LocalVariableTable