I'm having the strangest problem: maybe someone can help out.
I have a daemon written in Java (I've tried the latest Java 8 both OpenJDK and Oracle) on Linux. It will spawn some processes and there is a thread which watches to see if they're complete, meanwhile it will run other commands, some of which may kill the processes, etc.
Everything works absolutely fine almost all the time. However, one of the operations that the daemon can perform on its subprocesses is it can grab a core from them (without killing them: a core of the active process). It does this by loading a .so and calling it via JNI, which uses ptrace(PTRACE_ATTACH...) to pause the subprocess and grab core information, then it uses ptrace(PTRACE_DETACH...) to let it run again.
This also works fine and I can see the process operates correctly after the core has completed and all is fine.
Except, Java's Process object is now all wonky. Whenever I invoke exitValue() on this process once this has happened I always get back and exit code of 4991 (which if you decode it, means WIFSTOPPED with a signal value of 19, or SIGSTOP). That's not entirely surprising since the Linux man page states that ptrace() will look to parents as WIFSTOPPED. But the problem is that once the Process object reaches this state, it will never do anything else, even though the process actually goes back to running after the detach.
Even more critically, even after the process really exits, exitValue() still returns 4991, and the process is not reaped (it lives on in Z (zombie) state, as defunct) and will never go away, until my daemon is killed whereupon init will inherit, and reap, the zombie processes.
I've looked at the value of isAlive() (says no) and I've tried to run waitFor(0, TimeUnit.SECONDS) (says not running) but none of them get Process out of this broken state--this doesn't surprise me too much since my reading suggests these methods are actually implemented in terms of the exitValue() method anyway.
This appears to me like a bug in Java Process but I'm not sure... I've tried reproducing it by attaching GDB to the process then detaching it, but that doesn't show the same problem. Similarly just using SIGSTOP / SIGCONT doesn't do it.
Anyone have any hints or thoughts?
Related
To be clear, this is a upstart/linux debugging problem not a java problem per-se.
I have a java application installing a shutdownhook. It shows some funny behaviour in ubuntu-GNOME, namely that the shutdown hook never run if a restart or power off were scheduled. At first i thought it was a problem with my shutdown hook, so i simplified it until it was only writing a line to file (yes i know about the log4j2 logger problem with shutdownhooks so i disabled theirs too). Then when that didn't work i started hacking /etc/init/sendsigs
I added this to the beginning of the do_stop function:
app="$(jps | grep appname.jar | cut -d' ' -f1)"
echo "$app" >> "/home/i30817/output.txt"
sure enough, that showed that it was no longer running, so the shutdown hooks were never activated by sendsigs
Then i used lastcomm from here replacing my edit of sendsigs by:
echo `/home/i30817/lastcomm` > "/home/i30817/output.txt"
And it told me that the java process exited with 1 and was not signaled:
java X i30817 ?? 10.26 secs Sun Mar 2 12:44 E 1
but this still didn't help me find what actually killed it and why. This problem is not reproducible with a smaller example, so it's probably something in the larger application (but not the shutdown hook, since it was minimized) that doesn't like the shutdown process and manages to kill the process, but i can't figure it out... redirecting the process output to a file doesn't say anything either eg:
java -jar /home/i30817/Documents/projects/app/dist/app.jar > allout.text 2>&1
is empty of everything but normal app output
Can you help me figure out this? There are a lot of duplicate questions about the same thing too (but they think it's the shutdownhooks malfunctioning).
edit: more detail, now that i understand the problem a bit better. I think now that processes not being there on sendsigs is normal. Java applications, and maybe others use a protocol from the window manager where SIGHUP, SIGHUP and SIGCONT is sent on shutdown/logout. The JVM hooks SIGHUP to launch the shutdown hooks. I tested this with a very small example that only adds a shutdownhook and has a infinite cycle on main, and ran it with a system tap script in the background:
java -jar app.jar
and in another shell
sudo stap -o process.txt sigkill.stp
However when i tried that with my application i think i found the culprit:
PROCESS: SIGSEGV java.signal_generate sent to java 2280
but don't really know what to do about it considering there is no thread dump or anything and this is strange to reproduce (only my app, only during shutdown).
edit2: now i suspect the reason for the 'abrupt' termination without core dump is the ulimit during shutdown. So i'm trying to solve that in preparation for a bug report. I edited /etc/security/limits.conf to add this and rebooted
* soft core unlimited
root hard core unlimited
* hard rss 10000
(fs.suid_dumpable=2 was set by ubuntu, no apparmor i think)
but during shutdown i edited /etc/init.d/sendsigs again to print ulimit -a and sleep for 30 seconds before killing the processes, and it seems that during reboot the ulimit gets reset again? And moreover, it had a different output like it was using another executable version, for instance instead of saying 'core file size' it had 'core(dump)' or something like that).
edit3: ah, i need to have fs.suid_dumpable=1 instead - gonna try now.
Maybe the init ulimit doesn't matter for shutdown core dump triggering. After all the jvm was executed from the user env so it should be using the user ulimit.
edit4: eh. After much commenting of code i reached the following conclusion that i could have reached from RTFM:
the sigsegvs are harmless.
the non-zero exit code is not.
If the AWT is still up, the signal is always non zero and the shutdown hooks never run. Even a small example still prevents execution of shutdown hooks in linux reboot if a JFrame is up (unlike windows, where they will start). Looking at the source, the application shutdownhooks are run on a slot by themselves, slot 1. I bet slot '0' is the AWT and that is halting the system somehow.
I guess it's time to check the package private signal handling libs to see if i can get SIGHUP before the JVM decides to terminate everything without even giving the opportunity for cleanup code to run.
According to docs
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly....
If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.
Unix daemon runs a script a loop, the script calls a java program: java {java_args} myClas.jar
The java program is heavy program with multiple threads.
The problem is very strange: First execution works as expected.
But the second execution is stuck some where and I can't find a reason (very hard to debug this).
Is there a possibility that when first execution is finished there are still not-cleaned resources or threads left from this execution?
If yes, is it possible to clean and kill everything right after process completes?
If by resources, you mean threads, then no. When the VM shuts down, everything on the heap, all threads, objects and monitors are disposed of. However if you're depending on the existence/absence of a file for locking or something similar, a deadlock is possible. Also, is it possible that the first process is still running when you launch the second one?
If your java process is stuck on the second run, you can attach jvisualvm to it and should be able to figure out where it's stuck.
It is possible to kill a thread that is in state RUNNING in a non programatically way?
I know that top command in *nix can show threads. Can I kill the thread in the OS?
I'd like to know if there is a way to link a thread to a process so I can kill only that specific thread and not the application.
We had a bug in our code that kept a thread in state RUNNING in a synchronized method. The thread kept the lock on the object "hanging" the application.
The bug is fixed. But I wonder if is possible.
The short answer is "maybe, but you should not and most of the time it won't work either".
The long answer is:
"Maybe..."
Some JVM implementation map java threads to OS threads and some do not. If the JVM does a mapping to a native OS thread, you might be able to kill that thread with some process tool that the OS provides (like kill on *nix). If the JVM does green threads, meaning it doesn't map a Java thread to an OS level thread, then you are basically out of luck using OS level tools. Luckily only very few JVM implementations do this. An approach that can be used regardless in which way the JVM organizes it's threads, is using the java debugger. This article describes the procedure of doing it: http://www.rhcedan.com/2010/06/22/killing-a-java-thread/.
"but you should not do it"
Killing a thread on the OS level will almost certainly leave the JVM in an undefined state (read "jvm might crash or delete all files on your disk or do whatever it fricking pleases to do"). Even when going the debugger way, only a very small amount of java applications (read "no application made on this planet") will properly handle the event that an outside application is killing one of it's threads. As a result these applications will be put in an undefined state (read "application might crash or delete all files on your disk or do whatever it fricking pleases to do").
"and most of the time it won't work either"
If the thread is really stuck with some blocked IO etc, then killing the thread won't work, it will just not respond. If a program is stuck it's probably better to kill the whole program, find the issue with the program and fix it instead of killing a single thread.
For all your doubts on killing a thread, refer this:
http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
On linux, there is a tkill(int tid, int sig) command, similar to kill.
On windows, ProcessExplorer can do it from gui, don't know if there is anything with cli.
I am running a java app as daemon on a linux machine using a customized shell script.
Since I am new to java and linux, I want to know is it possible that the app itself resurrects itself(just like restart) and recovers from cases like app crashing, unhandled exceptions or out of memory etc.
thanks in advance
Ashish Sharma
The JVM is designed to die when there is an unrecoverable error. The ones you described fall in this category.
You could, however, easily write a shell script or a Python script that checks if the process is alive, and if it is dead, waits a few seconds and revive it. As a hint to doing this, the Unix command "pgrep" is your friend, as you can check for the exact command line used to fire a JVM (and thus including the starting class file). This way, you can determine if that specific JVM instance is running, and restart it.
All that being said, you may want to add some reporting or logging capability and check if often, because it is too easy to assume that things are ok when in fact the daemon is dying every few minutes. Make sure you've done what you could to prevent it from dying before resurrecting it.
There are Wrappers that can handle that, like Java Service Wrapper (Be aware, that the Community Edition ist under GPL) and some alternatives, mentioned here
To be honest, relaunching the daemon without any question after a crash is probably not a good idea; well it depends greatly on the type of processing achieved by your daemon, but if for example it processes files from a given directory, or requests coming from a queue manager, and the file / message contains some unexpected data causing the crash, relaunching the daemon would make it crash again immediately (excepting when the file / message is removed no matter it has been correctly processed or not, but as well it seems not to be a good idea).
In short, it's probably better to track down the possible crash reasons and fix them when possible (or at least log the the problem and go ahead, provided that the log message would ever be scanned to warn at last a human being, so some action can be engaged upon such "failures").
Anyway if you have very good reasons to do such, a solution even simpler than "checking that the process is alive" (as it would probably in some way involve some "ps -blahblah" stuff), you could just put the java program launching in a shell "while true" loop as follows :
while true
do
# launch the java program here, no background
# when crashing, the shell will be given hand back
java -classpath blahblah...
echo "program crashed, relaunching it..."
done
On unix based systems, you may use "inittab" to specify the program. If process dies, it is re-started by OS.(respawn)
I am not sure if the app itself can handle such crashes. You could write a shell script in linux which could be running as a cron job itself to manage the app, checking if the java app is running on scheduled intervals and if not, it will restart it automatically.
guys, I encounter a confusing issue! I want to invoke a executable JAR to compute PI from my main java applicaion using runtime.exec(), which create a new JVM for running the executable JAR. My issue is that when the PI computation is done, the JVM is still alive. my main java application has no idea whether PI computation is finished or not. And I also want when the PI computation is done, the JVM could be shutdown! How can I implement that! ThankS!!
When you call Runtime.exec() you will get a Process object back. You need to call waitFor() on this.
You will also need to capture the stdout/stderr streams (in separate threads to prevent blocking - see this answer for more info).
This all leaves aside why you're doing this in a separate JVM, and why you can't load the relevant classes into your current app and run the library locally.
To answer the second part of your question, the JVM always exits when no non-daemon threads are still running. Or in plainer speech, when your application is "done" and the main method exits without leaving any threads running in the background, the JVM will finish.
This is true regardless of whether you launch the Java process yourself from your desktop/command line, or fire it off via Runtime.exec() (which is broadly equivalent). So when your Pi calculation terminates it will shut down the JVM you spawned, and when your original program finishes then its JVM will also exit.
Though I agree completely with Brian here, I can't see the benefit in running a Java app as a separate process when you should be able to just run it in the original JVM (barring some really unusual environmental stuff such as setting niceness or processor affinity of the various processes).
check what the jar does when you run it standalone, maybe its waiting for input and therefor it will never exit