Method breakpoints may dramatically slow down debugging - java

Whenever adding a breakpoint to the line of a method declaration (in Intellij IDEA or Android Studio), a popup appears:
Method breakpoints may dramatically slow down debugging
Why would it dramatically slow down debugging, is my question? What is different about putting the breakpoint on the first line of the function?
Thanks!

I looked around a little, and saw this post in the Intellij Documetation:
Method Breakpoint
Method breakpoints act in response to the program entering or exiting a particular method. They let you target your debugging sessions by method you wish to investigate, rather than by line number. Method breakpoints let you follow the program flow at the method level as well as check entry and exit conditions. Note that using method breakpoints can slow down the application you are debugging.
I guess it stops the program right before it enters the method, so that you can evaluate the parameters and such before entering the method.
The reason it dramatically slows down is (This is what I can gather, because that is all I could find on method breakpoints in Intellij's documentation) that it has to:
let you follow the program flow at the method level as well as check entry and exit conditions
and I suppose that would take a lot longer than just halting the program's execution

My understanding is that the code must be run interpretively (instead of using JIT to pre-compile?) when the breakpoint is set on method entry.
If you set the breakpoint on the first line of the method instead, I suspect a line number index into the code can be used to simply swap a break opcode for the original opcode, so the app runs full speed. (which still seems pretty slow to me when debugging ;)

There is a simple explanation from the IntelliJ Team: "Method breakpoints will slow down debugger a lot because of the JVM design, they are expensive to evaluate"
https://intellij-support.jetbrains.com/hc/en-us/articles/206544799-Java-slow-performance-or-hangups-when-starting-debugger-and-stepping

Related

Finding which method is causing a NPE in Eclipse

I have an object that has a set of methods called on it like:
objectName.method1().method2().method3();
and I want to know which one of those methods is causing the NullPointerException to be thrown. Is there a way to do this in the Eclipse debugger?
If you want to know which specific value was unexpectedly null (e.g objectName or return value from method1() or method2()), then I recommend splitting this logic into multiple lines. Then, you'll be able to set specific breakpoints in the debugger and step to the exact failing line of code.
This has benefits when running in production too. If it happens after you deploy or in a live customer environment, then you'll get a more specific line number in the stack trace that points to the exact line of code with the problem.
This can be done with some careful stepping in Eclipse debugger. Put a breakpoint on the line you are describing. If you have local variables available in bytecode, then you will immediately know it the first call causes problems by looking at a value of objectName. If it is null, you know that it is the first call.
If not, step into the method (F5). This will bring you to the implementation of first method. Then you can immediately return from it by stepping out (step return - F7). You should be back at the orignal line with debugger ready to step through the next method. You continue by stepping into again (F5). That should take you to the implementation of the next method. If you arrived there, then there is still no exception. Step return (F7) again.
Continue until you get to some exception handler instead of the method you wanted to step into. This is the one you are after, or perhaps the one before it, because that one returned null.
You can also play with "Run to line" function (default Ctrl + R) to do that a bit more easily.

Breakpoint "concurrency" in Intellij

Lets say I have a class that initiates two threads Thread_A and Thread_B, each doing some calculations and ocassionally using a subroutine of my the class. (don't worry about data sharing, lets say it's a log line or imagine the subroutine is a method in a Java library) I want to know if there is a way of conditioning a breakpoint inside this subroutine to the subroutine having been called from say thread_A, but not B, or say a certain breakpoint having been hit prior to this breakpoint.
Obviously I can always go tho the frames tab in the debug window and see the caller thread, but it is tedious. It might be the case that thread_A accesses the subroutine much less often than thread_B. I don't want to have to see all the breakpoints which are initiated by Thread_B.
The way I currently do it, is setting up global flag variables and manipulating them just before calling the routine. I then have my breakpoint's condition depened on the flag variable. However that is probably not very thread-safe and not very clean.
What is the correct way of doing this? Out of curisoity, is there any other IDE for any other language that does this?
is the code that spwaned the threads your's ?
if so you could set unique names on the threads and use those names to
distinguish your threads when using breakpoint conditions.
e.g.
//spwaning the thread
Thread threadA=...
threadA.setName("thread-A");
// IntelliJ
Condition : Thread.currentThread().getName().equals("thread-A")

Debug-Execution Adventure

I debugged my java code. It didn't give any errors.But when i executed it (it isn't giving errors either, but) the code didn't successfully terminate. This is very funny. But is that even possible?
sure, when the slowdown introduced by debugger does mask some race condition, but this normally only applies to multi-threading or networking code.
Yes it is possible that code works when debugging and doesn't work when running. Two possible reasons I can think of right now are
Concurrency in case of multithreading: if your debugger stops on a breakpoint, timing between multiple threads can change which can influence the behaviour
When debugging, you can trigger certain parts of the code multiple times (more than when it has been executed without debugging), like for example via the toString method or via doing inspects or having some watch expression configured
Yes, your code can be syntactically correct (and thus might run without any errors) but may be semantically incorrect.
Assume the following:
public int add( int operand1, int operand2)
{
return operant1 - operand2;
}
This would run without errors but still be incorrect due to logic/implementation error.
So, it IS possible to get wrong results by otherwise smoothly running code.

Detect Who Created a Thread (w. Eclipse)

How can I find out who created a Thread in Java?
Imagine the following: You use ~30 third party JARs in a complex plugin environment. You start it up, run lots of code, do some calculations and finally call shutdown().
This life-cycle usually works fine, except that on every run some (non-daemonic) threads remain dangling. This would be no problem if every shutdown was the last shutdown, I could simply run System.exit() in that case. However, this cycle may run several times and it's producing more garbage every pass.
So, what should I do? I see the threads in Eclipse's Debug View. I see their stack traces, but they don't contain any hint about their origin. No creator's stack trace, no distinguishable class name, nothing.
Does anyone have an idea how to address this problem?
Okay, I was able to solve (sort of) the problem on my own: I put a breakpoint into
Thread.start()
and manually stepped through each invocation. This way I found out pretty quickly that Class.forName() initialized lot of static code which in return created these mysterious threads.
While I was able to solve my problem I still think the more general task still remains unaddressed.
I religiously name my threads (using Thread(Runnable, String), say), otherwise they end up with a generic and somewhat useless name. Dumping the threads will highlight what's running and (thus) what's created them. This doesn't solve 3rd party thread creation, I appreciate.
EDIT: The JavaSpecialist newsletter addressed this issue recently (Feb 2015) by using a security manager. See here for more details
MORE: A couple of details for using the JavaSpecialist technique: The SecurityManager API includes "checkAccess(newThreadBeingCreated)" that is called on the thread creator's thread. The new thread already has its "name" initialized. So in that method, you have access to both the thread creator's thread, and the new one, and can log / print etc. When I tried this the code being monitored started throwing access protection exceptions; I fixed that by calling it under a AccessController.doPriviledged(new PrivilegedAction() { ... } where the run() method called the code being monitored.
When debuging your Eclipse application, you can stop all thread by clicking org.eclipse.equinox.launcher.Main field in the debug view.
Then from there, for each thread you can see the stack trace and goes up to the thred run method.
Sometimes this can help and sometimes not.
As Brian said, it a good practice to name threads because it's the only way to easily identify "who created them"
Unfortunately it doesn't. Within Eclipse I see all the blocking threads, but their stack traces only reflect their internal state and (apparently) disclose no information about the location of their creation. Also from a look inside the object (using the Variables view) I was unable to elicit any further hints.
For local debugging purposes, one can attach a debugger to a Java application as early as possible.
Set a non-suspending breakpoint at the end of java.lang.Thread#init(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long, java.security.AccessControlContext, boolean) that will Evaluate and log the following:
"**" + getName() + "**\n" + Arrays.toString(Thread.currentThread().getStackTrace())
This will out the thread name and how the thread is created (stacktrace) that one can just scan through.

Why does the debugged program slow down so much when using method entry debugging?

I'm using jdi interfaces to create a debugger and when I use MethodEntryRequests to enable method entry tracing the debugged program slows down by factor of tens. I have set filter for main thread and suspend policy to SUSPEND_EVENT_THREAD. Classfilter is limited and if I print any received events it doesn't show more than couple of dozen of those so it shouldn't receive too much of them. I'm debugging locally and having followind kind of command-line with the debugged java program:
-Xdebug -Xrunjdwp:transport=dt_socket,suspend=y,server=y,address=1337
The short answer is that execution runs through the interpreter when method entries are set. I don't think there is anyway around this...
This used to be the case for all code running in debug mode but it was enhanced in 1.4... now HotSpot works for 'full-speed' debugging except in the case of method entries and exits, watchpoints and when single stepping or in methods that contain breakpoints.
2 reasons:
it has to add checks on every method entry
(there is no option to tweak just some methods)
method inlining becomes impossible
(so small methods runs 10-100x times slower)
same goes to profilers and .net apps
I would assume that the debugger needs to wake up for every method call to see if it matches the one(s) that were selected to break. Because it has to check every method call for a potential match before it can execute it is considerably slower than if it does not have to do all these checks.

Categories