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.
Related
We are seeing frequent timing issues in our nightly UI tests. The tests often fail because events performed by the java.awt.Robot have not completed before the test code tries to verifying the results.
We are code like using:
Point p = cb.getLocationOnScreen();
int m = 5;
if (cb.getWidth()<5||cb.getHeight()<5)
m=3;
System.out.println("Click at " + (p.x+m) + "," + (p.y+m));
robot.mouseMove(p.x + m, p.y + m);
robot.mousePress(MouseEvent.BUTTON1_MASK);
robot.mouseRelease(MouseEvent.BUTTON1_MASK);
robot.waitForIdle();
Thread.sleep(100);
// Verify results...
We keep having the bump up the Thread.sleep to ensure things complete on the event thread (things like clicking on a button or typing text) despite the java.awt.Robot.waitForIdle() call.
I found this question (Does java.awt.Robot.waitForIdle() wait for events to be dispatched?) which says to use java.awt.Toolkit.realSync(), but this is not an accessible method and with Java 9 coming, I'd rather not add any unnecessary reflection to our tests.
Are there better solutions? Or do people use realSync() or just increase the wait time until tests pass reliably?
UPDATE
I tried using sun.awt.SunToolkit.realSync(), but it is hanging in some tests and never returning. It looks like the EventThread is painting borders and such.
Looks like my only solution is to bump the sleep time up until the test can actually pass reliably. Yuck.
UPDATE 2
I figured out the first hang I had with realSync(). It was a problem in our code, where some paint code called a get method that called a set method which queued up another paint. Repeat forever.
Fixed our code and realSync() worked for a while, sort of. It still seems to return before it should. No idea why and I have no work around.
Also, I've seen realSync() hang and time out on my Linux box running under Java 1.7, but it works under Java 1.8. Very reliable tool here. /s
So, back the to original question. What is a decent way to tell when UI updates are done?
I came to the conclusion that I did need to use SunToolkit.realSync() and it seems to work correctly for Java 9 as well.
It seems, although I couldn't find any hard evidence, that realSync() waits for all graphics related threads while Robot.waitForIdle() and SwingUntilities.invokeLater() only wait for the Java EventThread to finish it's work.
If someone comes up with a better answer, I'd being will to accept that instead of my answer.
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
I'm looking for a way to break into the debugger from Java code, without setting a breakpoint in the IDE.
In Win32 there was DebugBreak(), in C# there's DebugBreak() Equivalent in C#, but I can't find anything in Java.
What I'm trying to do: say I have a wait with a 30s timeout, but in normal conditions that wait should always be <1s. I'd like to use ByteMan or something similar to wait with 1s timeout first, and break into the debugger if that wait timed out.
Not a direct answer to your question but in most IDE's you can set conditional breakpoints.
This would require you to set a timestamp variable in your code before the timeout and test its value in your breakpoint, after the timeout. You would trigger your breakpoint conditional if the delta is greater than your threshold.
The poster of this question has done exactly what I was looking for: Secure Debugging for Production JVMs
It reproduces the best feature of DebugBreak, that is you can attach the IDE to your program only after the "breakpoint" is hit.
I created this class
import com.sun.jna.Library;
public interface Kernel32 extends Library {
public void OutputDebugStringA(String Text);
public void DebugBreak();
}
then used it like this:
Kernel32 lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
lib.OutputDebugStringA("just before DebugBreak\n");
lib.DebugBreak();
and that's it. It calls native function
void WINAPI DebugBreak(void);
inside Kernel32.dll
You also need the jar file jna-4.4.0.jar
for easier situation inside IDE use also this example with breakpoint in body, poor mans conditional... (sorry for c# format)
if (lineNumber==6502)
{
System.out.println("BREAK"); //breakpoint here
}
Currently (as of 2021) you cannot accomplish this in Java in a way as convenient as DebugBreak is in C#.
The best you can do in Java is throw a custom runtime exception (say, class DebugBreakException extends RuntimeException) and pray that you have also remembered to add an "exception breakpoint" which breaks whenever this exception is thrown, even if the exception is handled.
Immediately after your code throws this exception, it catches it and dumps a message saying that this particular exception occurred.
If this message ever appears in the log, and yet your debugger did not break, then you know you forgot to add the necessary "exception breakpoint." (In other words, you have to pray that if this message ever gets logged, it will be noticed by someone.)
You can also be extra smart about it and add some code which checks how many milliseconds have elapsed from the moment the exception was thrown until it was caught; if more than, say, 10 milliseconds elapsed, then most probably there was a break into the debugger, so the logging of the message can be skipped. If the exception was caught within fewer than 10 milliseconds, then the debugger probably did not break, so you can proceed with logging the message.
It goes without saying that besides simply logging a message you can try to take as many additional measures as you can, like produce a beep, turn on a lamp, send an email to yourself, bang a gong, fry a motherboard, whatever it takes.
I have a piece of code that looks like this:
Algorithm a = null;
while(a == null)
{
a = grid.getAlgorithm();
}
getAlgorithm() in my Grid class returns some subtype of Algorithm depending on what the user chooses from some options.
My problem is that even after an algorithm is selected, the loop never terminates. However, that's not the tricky bit, if I simply place a System.out.println("Got here"); after my call to getAlgorithm(), the program runs perfectly fine and the loop terminates as intended.
My question is: why does adding that magic print statement suddenly make the loop terminate?
Moreover, this issue first came up when I started using my new laptop, I doubt that's related, but I figured it would be worth mentioning.
Edit: The program in question is NOT multithreaded. The code for getAlgorithm() is:
public Algorithm getAlgorithm ()
{
return algorithm;
}
Where algorithm is initially null, but will change value upon some user input.
I believe the issue has to deal with how grid.getAlgorithm is executed. If there is very little cost associated with executing the method, then your while loop will cycle very quickly as long the method continues to return null. That is often referred to as a busy wait.
Now it sounds like your new laptop is encountering a starvation issue which didn't manifest on your old computer. It is hard to say why but if you look at the link I included above, the Wikipedia article does indicate that busy waits do have unpredictable behavior. Maybe your old computer handles user IO better than your new laptop. Regardless, on your new laptop, that loop is taking resources away from whatever is handling your user IO hence it is starving the process that is responsible for breaking the loop.
You are doing active polling. This is a bad practice. You should at least let the polling thread sleep (with Thread.sleep). Since println does some io, it probably does just that. If your app is not multithreaded it is unlikely to work at all.
If this loop is to wait for user input in a GUI then ouch. Bad, bad idea and even with Thread.sleep() added I'd never recommend it. Instead, you most likely want to register an event listener on the component in question, and only have the validation code fire off when the contents change.
It's more than likely you're program is locking up because you've reached some form of deadlock more than anything else, especially if your application is multithreaded. Rather than try to solve this issue and hack your way round it, I'd seriously consider redesigning how this part of the application works.
You should check getAlgorithm(), there must be something wrong in the method.
There are two scenarios:
Your code is really not meant to be multi-threaded. In this case you need to insert some sort of user input in the loop. Otherwise you might as well leave it as Algorithm a = grid.getAlgorithm(); and prevent the infinite loop.
Your code is multi-threaded in which case you have some sort of 'visibility' problem. Go to Atomicity, Visibility and Ordering or read Java Concurrency in Practice to learn more about visibility. Essentially it means that without some sort of synchronization between threads, the thread you are looping in may never find out that the value has changed due to optimizations the JVM may perform.
You did not mention any context around how this code is run. If it is a console based application and you started from a 'main' function, you would know if there was multi-threading. I am assuming this is not the case since you say there is no multithreading. Another option would be that this is a swing application in which case you should read Multithreaded Swing Applications. It might be a web application in which case a similar case to swing might apply.
In any case you could always debug the application to see which thread is writing to the 'algorithm' variable, then see which thread is reading from it.
I hope this is helpful. In any case, you may find more help if you give a little more context in your question. Especially for a question with such an intriguing title as 'Weird Java problem, while loop termination'.
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.