CAFE

WebLogic

[Trouble Shooting]Revelations on Java signal handling and termination

작성자Luke|작성시간08.12.30|조회수1,130 목록 댓글 0

http://www.ibm.com/developerworks/java/library/i-signalhandling/

 

Java Virtual Machine (JVM) signal handling and termination behavior got a makeover in version 1.3.1. Many Java developers might not know about the JVM's use of signals and the facilities it provides to an application during the final stages of the JVM's life. In this article, JVM engineer Chris White gives insight into why the JVM uses signal handlers and describes how to deploy your own application signal handlers without fear of compromising the JVM. This article also shows how to write your own hooks that can be called when the JVM terminates normally or in an application crash.
//

What is signal handling?

This article assumes a basic understanding of signal handling, Java, and Java Native Interface (JNI). It discusses the signal handling behavior of IBM's JVM 1.3.1 for

  • IBM OMVS on z/OS (OS/390), called z/OS in this article
  • IBM AIX
  • Microsoft Windows

Although this article also refers to Linux signal handling, IBM's latest release of the Java Virtual Machine on Linux is at 1.3.0, so the overall behavior will differ. For other JVMs and operating systems the techniques described in this article are applicable, but the overall behavior is likely to differ.

With signals, an operating system can interrupt a running application and cause it to enter a special handler function. Signals can be raised for many different reasons; for example, a SIGSEGV will be raised when a process attempts to access an address for which it does not have permission. A SIGINT might be raised when the user requests termination by typing CTRL-C. With a signal handler your application can trap signals and perform any necessary processing. In the case of a SIGSEGV your handler could report essential diagnostic information to help diagnose the fault, or even recover and thus improve the reliability of your application.

To install a signal handler for your native application use the system function sigaction() (on Unix type platforms) or signal() (on Windows or Unix platforms). In both cases, specify the number of the signal that is to be handled and a reference to your signal handler function. If the call is successful, a reference to the previously installed signal handler will be returned.

When a signal handler is installed for a signal it overrides any previously-installed handler for that signal. And, a signal handler is processed widely and hence services a signal sent to any thread. There are some interesting and fundamental differences between operating systems regarding signal handling. For all platforms, whenever a signal is directed at a particular thread (such as with a pthread_kill() or raise() system call, or when an exception occurs on that thread), the signal handler runs within that thread's context. However if a signal is raised at the process level, by another process such as SIGINT raised when CTRL-C is entered, then the behavior is platform-specific, as follows.

Operating system Behavior
On z/OS and AIX A single thread, chosen by the operating system, receives the signal.
Linux All threads receive the signal, and the signal handler is invoked on each thread. Linux threads are just separate processes that share the same address space, so it is also possible for another application to raise a signal on a specific thread.
Windows A new thread is created for executing the signal handler. This thread dies once the signal handler is complete.


The JVM's use of signals is platform-dependent; for certain platforms the JVM may use signals for efficient byte code interpretation, or for suspending, resuming, and interrupting threads. However, signals are used commonly across all JVMs with abnormal termination, where the JVM performs the necessary cleanup and attempts to gather useful diagnostic information for a dump.

By understanding how the JVM deals with signals and the processing it does on termination, you can exploit signal handling in your applications and handle abnormal termination reliably.

IBM JVM 1.3.1 improvements

With IBM's JVM 1.3.1, signal handling has been improved to give a consistent termination sequence and to ensure that the JVM behaves itself when signals raised for an application are not destined for the JVM. The reliability of the termination logic has also been greatly improved. In particular, the JVM can ensure that your Java application shutdown hooks are run under normal and interrupted exit (for example, CTRL-C) conditions. Abnormal termination of the JVM now returns the correct status to the operating system, and the resulting OS-generated diagnostic information gives an accurate account of the problem. Previously, on some platforms, a SIGABRT condition was generated that occasionally led to confusion.

Signals used by the JVM

The table below shows the signals used by the JVM for the platforms supported by IBM. The signals have been grouped in the table by type or use, as follows.

  • Exceptions (in red) - The operating system synchronously raises an appropriate exception signal whenever a fatal condition occurs.
  • Errors (in blue) - The JVM raises a SIGABRT if it detects a situation from which it cannot recover.
  • Interrupts (in green) - Interrupt signals are raised asynchronously, from outside a JVM process, to request shutdown.
  • Controls - Other signals used by the JVM for control purposes.

Table 1. Signals used by the JVM

Signal Name Description Disabled by -Xrs z/OS AIX Windows
SIGSEGV Incorrect access to memory (write to inaccessible memory) No
SIGILL Illegal instruction (attempt to invoke a unknown machine instruction) No
SIGFPE Floating point exception (divide by zero) No
SIGBUS Bus error (attempt to address nonexistent memory location) Yes
SIGSYS Bad system call issued Yes
SIGXCPU CPU time limit exceeded (you've been running too long!) Yes
SIGXFSZ File size limit exceeded Yes
SIGEMT EMT instruction (AIX specific) Yes
SIGABRT Abnormal termination. The JVM raises this signal whenever it detects a JVM fault. Yes
SIGINT Interactive attention (CTRL-C). JVM will exit normally. Yes
SIGTERM Termination request. JVM will exit normally. Yes
SIGHUP Hang up. JVM will exit normally. Yes
SIGUSR1 User defined. Used by some JVMs for internal control purposes. No
SIGUSR2 User defined. Used by some JVMs for internal control purposes. No
SIGQUIT A quit signal for a terminal. JVM uses this for taking Java core dumps. Yes
SIGBREAK A break signal from a terminal. JVM uses this for taking Java core dumps. Yes
SIGTRAP Internal for use by dbx or ptrace. Used by some JVMs for internal control purposes. Yes (not for AIX)
SIGPIPE A write to a pipe that is not being read. JVM ignores this. No
No Name (40) An AIX reserved signal. Used by the AIX JVM for internal control purposes. No

Note that -Xrs (reduce signal usage) is a JVM option that can be used to prevent the JVM from using most signals. See Sun's Java application launcher page (in Resources for more information).

How the JVM processes signals

When a signal is raised that is of interest to the JVM, a signal handler is called. This handler determines whether it has been called for a Java or non-Java thread. If the signal is for a Java thread, the JVM takes control of the signal handling. If the signal is for a non-Java thread, and the application that installed the JVM had previously installed its own handle for the signal, then control is given to that handler. Otherwise the signal is ignored (even if this is not the signal's default action). The one exception to this rule is on Windows, where for an externally generated signal (you enter CTRL-C or CTRL-BREAK, for example) a new thread is created to execute the signal handler. In this case the JVM signal handler assumes that the signal is for the JVM.

What are Java threads?

A Java thread is one that is known to the JVM. The following statements define when code is running as a Java or non-Java thread:

  • All Java code runs under a Java thread.
  • All native code called from Java code runs under a Java thread.
  • A native application thread that successfully calls JNI function: JNI_CreateJavaVM() or AttachCurrentThread(), becomes a Java thread.
  • A native application thread that successfully calls JNI function: DestroyJavaVM() or DetachCurrentThread(), becomes a non-Java thread.
  • All other native application threads will be non-Java threads.

For exception and error signals, as shown in the table above, the JVM enters a controlled shutdown sequence where it:

  • Outputs a Java core dump, to describe the JVM state at the point of failure
  • Calls any application installed abort hook
  • Performs the necessary cleanup to give a clean shutdown.

For interrupt signals the JVM also enters a controlled shutdown sequence, but this time it is treated as a normal termination that:

  • Runs all application shutdown hooks
  • Calls any application installed exit hook
  • Performs the necessary JVM cleanup.

The shutdown is identical to a call to the Java method System.exit().

Other signals used by the JVM are for internal control purposes and do not cause it to terminate. The only control signal of interest is SIGQUIT (on Unix type platforms) and SIGBREAK (on Windows), which cause a Java core dump to be generated.

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼