Stop at breakpoints only in certain thread - java

I have some multithreaded code and am trying to set up some breakpoints in Eclipse so I can do some debugging.
The breakpoint I want to set is in a class used by all of the threads. However, I only want the breakpoint to be hit when I am in the main thread. Is there a way to do this in Eclipse?
I have tried to use the 'conditional' breakpoint options but cannot get it to work.

Conditional breakpoint approach is good. The condition should looks like: Thread.currentThread().getName().equals("main").
If you want to set up a breakpoint for another thread you just have to change "main" to a thread-specific name, which can be provided via the Thread constructor.

You should be able to set up a conditional breakpoint by using a condition dependent on thread-local data. Two examples:
Thread.currentThread().getName(),
some value stored in a ThreadLocal.

There should be an item Filtering in the breakpoint properties dialog. There, you can limit the breakpoint to specific threads. But this only works when the program is already running since that dialog shows all threads from the running JVM.

Related

Eclipse conditional breakpoints and global variables?

I have a global variable
static int debugNumber;
and a breakpoint with a condition
debugNumber > 1
with Suspend thread, Conditional and Suspend when 'true' checked. Currently, if I pause the execution of the program and hover over the declaration the value displayed is 2. Still, this breakpoint doesn't break.
As far as I can see on Google and here at SE debugNumber > 1 should be fine. What am I doing wrong?
Just so we're clear: That line means: If code execution gets to this line (the line with the breakpoint), then do what breakpoints usually do: Freeze the thread (or if you've configured things to be that way, and pause all other threads, which is not the default). However, a conditional breakpoint means: Before breaking as usual, check the condition. If the condition is false, then don't do anything.
A conditional breakpoint is going to break as often, or less often, than a normal breakpoint, never more often.
It sounds like what you want is to 'breakpoint' every line in the codebase that sets the debugNumber variable, if the value it is being set to is 2 or higher. If that's what you want, make a 'watch' on debugNumber and configure the watch to break execution.
If that's not what you wanted, then, well, you made no mistakes in what you describes, so then it's one of a billion things that could be wrong:
The line with your breakpoint was never hit.
The debugNumber was 1 or less when it hit your breakpoint.
You used 'run' to start your application and not 'debug' (there's pretty much no reason to ever 'run' anything, always pick 'debug')
The global 'disable all breakpoints' toggle within eclipse has been toggled off. It's (unless you changed things) on the toolbar: a larger 'breakpoint dot' (blueish circle) with a big slash through it. It's a toggle button. Is it pressed in?
Eclipse debugger has desynced. It will throw you a dialog if this happens, but one of the options in this dialog is 'ignore now and in the future' (It's a more succint text than that, but that's the gist of it). If you ever pressed that, it can desync. The debug view will tell you. This can happen if you change compiled code as eclipse runs, or change signatures in your source files and save the source file in the middle of a run.
Many many more things

Forcefully terminating a thread I didn't write in Java

Everywhere I look about how to forcefully stop a thread in Java, I see "just do an exit variable check instead, your program is broken if you need to force kill."
I have a rather unique situation though. I am writing a Java program that dynamically loads and runs other Java classes in a separate thread. (No comments about security risks please, this is a very specific use case).
The trouble is, since other people will have written the classes that need to be loaded, there's no way to guarantee they'll implement the stop checking and whatnot correctly. I need a way to immediately terminate their thread, accepting all the risks involved. Basically I want to kill -9 their thread if I need to. How can I do this in Java?
Update: here's a bit more info:
This is actually an Android app
The user code depends on classes in my application
A user class must be annotated with #UserProgram in order to be "registered" by my application
The user also has the option of building their classes right into the application (by downloading a project with the internal classes already compiled into a libraries and putting their classes in a separate module) rather than having them dynamically loaded from a JAR.
The user classes extend from my template class which has a runUserProgram() method that they override. Inside that method, they are free to do anything they want. They can check isStopRequested() to see if I want them to stop, but I have no guarantee that they'll do that.
On startup, my application loads any JARs specified and scans both all the classes in the application and the classes in those JARs to find any classes annotated with the aforementioned annotation. Once a list of those classes is built, it is fed into the frontend where the UI provides a list of programs that can be run. Once a program is selected, a "start" button must be pressed to actually start it. When it is pressed, the button changes to a "stop" button and a callback is fired into the backend to load up the selected class in a new thread and call the runUserProgram() method. When the "stop" button is pressed, a variable is set which causes isStopRequested() to return true.
You can kill -9 it by running in its own process i.e. start with a ProcessBuilder and call Process.destroyForcibly() to kill it.
ProcessBuilder pb = new ProcessBuilder("java", "-cp", "myjar.jar");
pb.redirectErrorStream();
Process process = pb.start();
// do something with the program.
Scanner sc = new Scanner(process.getOutputStream());
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
// when done, possibly in another thread so it doesn't get blocked by reading.
process.waitFor(1, TimeUnit.SECONDS);
if (process.isAlive())
process.destroyForcibly();
Java 8 had Thread.stop(). The problem is that it could only work reasonably for very limited use cases, so limited you were better off using interrupts, and if the code isn't trusted, neither are any good.
There is the deprecated Thread.stop() but don't use it.
There is no way to cleanly terminate another thread without it cooperating.
The thread can be in a state where it allocated some memory, or added some objects to some global state, locked some mutexes, etc. If you kill it at the wrong moment, you risk leaking memory or even causing a deadlock.
It would be possible through JNI, under Windows there is a TerminateThread API that you can call, there is (hopefully) probably a similar thing under Android. The trouble will be getting the thread's native handle, you would need to obtain that when your user "program" is first loaded, probably by calling another JNI method from the thread in question as part of the initialisation process and getting the current thread handle from that.
I have not tried this myself, best case is that this "works" and kills the thread, but it is going to cause that thread to leak resources. Worst case is that it will leave the JVM in an inconsistent state internally, which will probably crash your entire application.
I really think this is a Bad Idea.
A better design, if you want to allow this, is to run your user code in another process and communicate with it via sockets or pipes. This way you can relatively safely terminate the other process if necessary. It's more work, but it's going to be a lot better in the long run.
You shold use Thread.interrupt().

Eclipse suspend a specific thread while letting others run

Is there a way for the debugger to pause a specific thread while letting the other ones run? I want to verify some locks I have are working properly and Im not sure how to induce certain conditions. Note that all the threads run through the same code, so any changes to the code will affect all threads, where as I only want to stop one thread.
You might want to look at testing frameworks like MultithreadedTC - which lets you programmatically control flow through the different threads during the test so you can cause race conditions and timeouts during testing.
If you have a convenient point in your code to set a breakpoint for that single thread, you can change the Suspend Policy of that breakpoint in its properties to only stop the current thread instead of the whole VM.
You can add a method to do a sleep in the thread. Then you can call that method with junit or a simple POJO.
I was able to sort of fix my own problem by basically putting the following code in the thread code -
if(Thread.currentThread.getName()="thread1"){
Thread.currentThread.sleep(5000);
}
This way only thread 1 sleeps. It worked well enough that I saw my locks working, but this isnt really a good solution I feel. Perhaps someone can make something better?

How to Identify threads in Eclipse Debug Perspective?

I am developing a Java application which has some threads. I print in the console the threadId, for instance 17, 18, 19, and so on.
But when I have the debug perspective open, I have this "Debug" window (most up-left window), which shows me the current threads, but they use [Thread-2], [thread-3]. The numbers not necessarly match the ThreadIds.
Is there any way so I can correlate the ThreadId I get in my console to the thread shown in the "Debug" window?
I don't know of a way to do that.
However, there is another approach. Those thread names are generated automatically by the Thread constructor you are using. However, there is a method called Thread.setName() that allows you to change the thread's name. You could possibly tweak your application to change the names of the threads that it creates to match the thread's ids.
There is nothing as such in Eclipse, but if you want to find which thread, then add debugging point on the code and call the
Thread.currentThread();
to find out the thread, which is currently executing.
Watch this thread for more information on the same.
http://dev.eclipse.org/mhonarc/lists/platform-debug-dev/msg00845.html
Instead of printing the Thread ID, you could print the thread name. Thread.currentThread().getName(). That is the name shown in the debugger.

Java program only works with Breakpoints in Netbeans

I'm working on a multithreaded program in Java that uses a shared array to pass data between threads. It's being developed in Netbeans 6.7.1.
One of the threads only seems to work when a breakpoint is placed in it, it doesnt matter where it is.
Running in debug mode with no breakpoints acts the same as running in release - the expected output never arrives.
I can't tell where the problem occurs, as the moment a breakpoint is added and I press continue, it works as expected.
How can I narrow down where/why this problem occurs?
Example code:
result = utils.isBufferFull(AudioDuplex.voiceArray);
if(result == true) {
System.out.println("Taking copy");
voiceArray = AudioDuplex.voiceArray;//.clone();
utils.clearBuffer(AudioDuplex.voiceArray);
}
If a breakpoint is placed on line 2, it is never hit.
A breakpoint on line 3 will be hit, and the expected output will arrive.
It's impossible to tell exactly what's wrong without a lengthier code sample, but in my experience, this kind of behavior is typical of unrecognized producer-consumer problems (see http://en.wikipedia.org/wiki/Producer-consumer_problem).
Basically, what's probably happening is that your producer thread does not have the data available when the consumer thread is requesting it. The basic solution is to keep a semaphore (there is a Sempahore class in java afaik). The producer would post when it has the data, the consumer would wait until the producer posts.
What you're seeing with the break point is you stopping the consumer thread for a long enough period that the producer can offer something. When you don't break, the consumer runs normally, and exits before the producer has anything.
Write the values of the involved variables to a log file, the console or add them to an array and print them as soon as you get the error.
Your problem is probably a runtime issue (a second thread updates an involved variable). Since breakpoints only stop the active thread, the second thread gets its work done so the code works.

Categories

Resources