Skip to content

Implement an initial version of instrumentation conditional breakpoints - #14

Open
Alexey Merkulov (steelart) wants to merge 8 commits into
mainfrom
steelart/bp-instrumentation
Open

Alexey Merkulov (steelart) wants to merge 8 commits into
mainfrom
steelart/bp-instrumentation

Conversation

@steelart

Copy link
Copy Markdown
Collaborator

No description provided.

Comment thread src/main/java/com/intellij/rt/debugger/agent/ClassTransformer.java Outdated
Comment thread src/main/java/com/intellij/rt/debugger/agent/ClassTransformer.java Outdated

private static void addPoint(String propertyKey, String propertyValue) {
if (propertyKey.startsWith("instrumentation.condition.breakpoint")) {
String[] split = propertyValue.split(" ");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Classes, methods, and arguments might have spaces in their names (e.g., ReactorDebuggerWithAgentTest#test with debug agent()). We need something more sophisticated here.

It also affects stack trace capturing, but "capture" and "insertion" points are likely to be in some libraries or other core classes, luckily for us, without spaces. But breakpoints could be placed anywhere.

It might worth it, to develop a uniform way to pass these names to the agent.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose to create a ticket and support this case a little bit later

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, don't forget to create and then resolve this.

}

private static Map<Integer, InstrumentationBreakpointInfo> getLineNumbers(String methodName, Map<String, Map<Integer, InstrumentationBreakpointInfo>> methods) {
int index = methodName.indexOf("$lambda$");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We absolutely need more comments here. It's unclear what's happening here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is Kotlin lambda encoding. Also need to check similar cases for Java. Likely this place will be updated later. Also, it seems I'm not fully correct here. Like bp before func { inside() } will call twice now (instead of the old version). So, likely need to change the calling side so to extract the correct lambda name.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully get it. But we still need more comments in the code.

boolean isFound = false;
for (LocalVariableNode localVariableNode : method.localVariables) {
if (localVariableNode.name.equals(argumentName) &&
method.instructions.indexOf(localVariableNode.start) <= instructionIndex &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't like this approach with loading of the whole class into ClassNode tree. All this stuff could be done more efficiently using visitors. Is it your intentional choice or just a prototype?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is executed only for classes with conditional breakpoints. I suspect that you never see a difference in real live between this implementation and the "optimized" one. I would preserve it for now it least. Also, I suspect, that the node representation might give us some other advantage.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other advantages? For me it looks like using the wrong tool for the task, it's not only about performance.

I have quite a strong opinion here, we might ask Egor for the third opinion.

mv.visitJumpInsn(Opcodes.GOTO, afterIf);

mv.visitLabel(catchBlock);
mv.visitIntInsn(Opcodes.BIPUSH, instrumentationId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Then please fix the comparison, instrumentationId == Short.MAX_VALUE isn't a problem. Anything greater is a problem. Otherwise it looks confusing.


private static void addPoint(String propertyKey, String propertyValue) {
if (propertyKey.startsWith("instrumentation.condition.breakpoint")) {
String[] split = propertyValue.split(" ");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, don't forget to create and then resolve this.

}

private static Map<Integer, InstrumentationBreakpointInfo> getLineNumbers(String methodName, Map<String, Map<Integer, InstrumentationBreakpointInfo>> methods) {
int index = methodName.indexOf("$lambda$");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully get it. But we still need more comments in the code.

Map<Integer, InstrumentationBreakpointInfo> lineNumbers = getLineNumbers(methodName, methods);
if (lineNumbers == null) {
lineNumbers = new LinkedHashMap<>();
methods.put(methodName, lineNumbers);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

            String whereMethodName = methodName.substring(0, index);
            return methods.get(whereMethodName);

But you get by substring there and put by full name here. What am I missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants