From the beginning of https://en.wikipedia.org/wiki/Interrupt, it says that a software interrupt can be caused by an exceptional condition in the processor itself (often called a trap or exception).
In many programming languages (C++, Java, Python,...), there are language supports for catching and handling exceptions defined by default, and also exceptions self-defined. For example, try {...} catch .... Let me called both kinds of exceptions "language-supported exceptions" (because I don't know what is the right terminology).
Do the language-supported exceptions count as software interrupts?
When a language-supported exception happens, does the same thing
happen as for handling a software interrupt? Specifically, does the
cpu save the current process into stacks, and then switch to run the
OS kernel which then calls the exception handler, and after
finishing running the handler, resume running the saved process?
No, java language exception has nothing to do with software interrupts
Java language exception just initiates some exception handling code within same process and thread.
No.
An interrupt causes an interrupt handler to be invoked. Once that handler is complete the original code will continue executing from the place it was at when the interrupt happened.
Exceptions are handled in a catch block. Program flow is directly affected.
From your link:
The processor responds by suspending its current activities, saving its state, and executing a function called an interrupt handler (or an interrupt service routine, ISR) to deal with the event. This interruption is temporary, and, after the interrupt handler finishes, the processor resumes normal activities.
Question 1 No. As per your wiki reference one explanation is
The former is often called a trap or exception and is used for
errors or events occurring during program execution that are
exceptional enough that they cannot be handled within the program
itself.
You are able to handle any Java exception within your program. So that is one difference. A Java exception could be triggered by an exceptional condition within the processor but the exception handler in your program is responding to an event generated within the JVM, not directly responding to a software interrupt. The more conventional way to think of software interrputs is
Software interrupt instructions function similarly to subroutine
calls and are used for a variety of purposes, such as to request
services from low-level system software such as device drivers.
Do a little research about how to invoke BIOS or MS/DOS services using the INT x86 instruction (this generates a software interrupt).
Questionn 2. Not necessarily. The JVM can generate an exception that has nothing to do with an exceptional processor condition. Think null reference.
No. Exceptions don't count as software interrupts, nor do they act as software interrupts.
Specifically, language-supported exceptions don't need to call the operating system; a context switch is generally unnecessary. Instead, throwing an exception makes a call to user-side code which understands how to look for handlers, unwind the call stack, and so forth, for that particular language.
To look at it another way: a general-purpose operating system will not know or care about the language-specific details necessary to handle language-supported exceptions. Software interrupts fall under the category of the operating system's ABI, which does not need to be remotely similar to the internal standards of a given language implementation.
Related
Good Day!
I have been going through the Java Docs & some online resources on properly handling the InterruptedException due to bug reported by SonarQube. But not sure if I 100% understood if Interruption flag status always has to be restored whenever InterruptedException occurs inside a place where we can't throw exception for Ex: Runnable implementation.
Lets consider below replicated demo example code, where the main method is responsible for initiating some async method.The async method makes the Http GET request and processes(by taking runnable as argument to the addListener method) the response asynchronously.
Note : Now my query is Do I have to restore Interruption status flag at line#35. Why asking this is because,
This is my complete program, and nowhere am interrupting the task-thread which processes the actual GET request's response. But Interruption can happen due to various factors which I understand. But my requirement is very simple to always return back some default response no matter what exception I get, even if it is InterruptedException. So, even without restoring the flag, my intention/requirement gets fulfilled i.e to complete the CompletableFuture with some default response.
And nowhere in my code I am going check for Thread.interrupted() OR Thread.currentThread().isInterrupted() because I don't want to handle this as my requirement already got fulfilled by returning back default response.
After capturing the InterruptedException and completing the Future with some default response, am not processing anything further within this thread(Runnable).
After executing the InterruptedException catch block, next my Main Thread will start executing with the received default response. And my Main Thread OR Parent Thread doesn't want to know OR doesn't care about if InterruptedException ever occurred-or-not. All it cares about is some valid response.
Incase if I still want to restore the Interruption flag status, could
someone please explain why to restore the same, and how can my code go
wrong if I don't restore it?
. Because, as I said in above 4 points my requirement gets fulfilled even without restoring the flag.
Any enlightment/clarification on this topic for the above exact scenario is highly appreciatable.
Thanks in Advance :)
In your program there you probably don't need to handle InterruptedException indeed.
But in a general case swallowing InterruptedException is a bad idea.
The main reason is that Thread.interrupt() (which causes InterruptedException) is the only way to interrupt many blocking operations provided by Java's standard library.
For instance, the proper handling of InterruptedException is typically required when we want to gracefully shutdown our application (i.e. when we want to close files, network connections and other resources before shutdown).
Some information about this can be found in Thread.interrupt() javadocs.
Also I would recommend this SO answer and related chapters in "Java Concurrency In Practice", mentioned there.
In Java, we use System.exit(int) to exit the program.
The reason for an "exit value" in C was that the exit value was used to check for errors in a program. But in Java, errors are reflected by an Exception being thrown, thus they can be handled easily. So why do we have exit values in Java at all?
exit values are returned to the calling program e.g. the shell. An Exception cannot be caught by an external program.
BTW When you throw an Exception it is caught by that thread or that thread dies, the finally blocks are still called for that thread. When you call System.exit(), all threads stop immediately and finally blocks are not called.
For the same reason.
Exit codes are exclusively used by parties and applications outside of the program for debugging and handling purposes. A super-application can definitely handle a return code better than trying to parse a stack trace.
Also, if you are creating an application for an end-user, you would much rather exit gracefully from your app than post a bunch of stack trace information, for a couple of reasons: one, you will just be scaring them with lots of crazy-looking techno-gibberish, and two, stack traces often reveal sensitive and confidential information about the way the program is structured fundamentally (giving a potential attacker more knowledge about the system).
For a real-world example, I was working on a Java Batch program which used exit codes for its jobs. A user could see whether the job executed successfully or not based on whether the exit code was "0". If it was anything else, they could contact technical support, armed with the additional information of the exit code, and the help desk would have all the necessary information based on that exit code to help them out. It works much nicer than trying to ask a non-technical end-user, "Okay, so what Exception are you getting?"
exit values are returned to the callers to signal the successful or insuccessful completion of the program. The caller may not be able to catch the exception and handle it accordingly.
For eg. 0 exit value means successful completion whereas non-zero return value means some error in execution.
Also, System.exit() will make all the threads in the application to stop at that point itself.
Long story short, Exit codes are simplified signals to the user who encounters an exception while running a Java program. Since we assume that most of the users do not understand stack trace data of an exception, these simple non zero custom code will tell them that something is wrong and this should be reported to the vendor. So the vendor gets the code and he knows the stack trace associated with that code and tries to repair the system. This is an abstraction provided by the programmers so that users don't have to read and report voluminous stack traces. A very good analogy here is the getErrorCode() method in SQLException class. This method also closes the current JVM that is running on the client machine. This implies that this terminates all the threads that are in the JVM. This method calls the exit method in the class Java.lang.Runtime. If you go to the documentation of this method, you will understand how virtual machine is shut down.
This is the link
http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#exit%28int%29
I have been reading the JLS and I encountered the section 11.1.3. Asynchronous Exceptions from which I quote:
Most exceptions occur synchronously as a result of an action by the
thread in which they occur, and at a point in the program that is
specified to possibly result in such an exception. An asynchronous
exception is, by contrast, an exception that can potentially occur at
any point in the execution of a program.
And
Asynchronous exceptions occur only as a result of:
[...]
An internal error or resource limitation in the Java virtual machine that prevents it from implementing the semantics of the
Java programming language. In this case, the asynchronous exception
that is thrown is an instance of a subclass of VirtualMachineError.
Is it possible to catch such exceptions for logging purposes or notification (because I believe such thing is unrecoverable)? How can I achieve such thing?
You can catch such exceptions just like any other exception. The only problem is that they may occur at any place in your program, so catching them reliably is hard. You would basically have to wrap the run method of all threads and the main method in a try..catch block, but you can't do that for threads you don't control (like the Swing EDT, or threads for timers etc.).
Also catching any subclass of Error is usually not recommended, because the JVM may be in an unstable state, which might lead to a further failure (for example in the case of OutOfMemoryError, you might not even have enough memory to to the exception handling). However, logging would be a valid reason for catching Errors in my eyes.
My suggested solution would be to use an uncaught exception handler for this by setting it as the default exception handler. In this handler you will get all exceptions and errors, if they are not caught anywhere in the code, and you can try to log them.
There is no point of catching these exceptions (Subclasses of VirtualMachineError) as you have no indecattion in which state the pogram is at the point, the Doc saies about Virtual Machine Errors:
A Java virtual machine implementation throws an object that is an
instance of a subclass of the class VirtualMethodError when an
internal error or resource limitation prevents it from implementing
the semantics described in this chapter. This specification cannot
predict where internal errors or resource limitations may be
encountered and does not mandate precisely when they can be reported.
so assuming you get in an OutOfMemoryError or an UnknownError there isnt much you can do about it, and once your vritualmashine doesnt work properly you cant provide the user anyhelp as your program isnt working properly as well, besides you have no idea at what time, point, and reason it happends since its not a code error that was caused from your program.
We have a C++ application with an embedded JVM (Sun's). Because we register our own signal handlers, it's recommended we do so before initializing the JVM since it installs its own handlers (see here).
From what I understood, the JVM knows internally if the signal originated from its own code and if not it passes it along the chain - to our handlers.
What we started seeing is that we're getting SIGPIPEs, with a call stack that looks roughly like this (the top entry is our signal handler):
/.../libos_independent_utilities.so(_ZN2os32smart_synchronous_signal_handlerEiP7siginfoPv+0x9) [0x2b124f7a3989]
/.../jvm/jre/lib/amd64/server/libjvm.so [0x2aaaab05dc6c]
/.../jvm/jre/lib/amd64/server/libjvm.so [0x2aaaab05bffb]
/.../jvm/jre/lib/amd64/server/libjvm.so(JVM_handle_linux_signal+0x718) [0x2aaaab05e878]
/.../jvm/jre/lib/amd64/server/libjvm.so [0x2aaaab05bf0e]
/lib64/libpthread.so.0 [0x3c2140e4c0]
/lib64/libpthread.so.0(send+0x91) [0x3c2140d841]
/.../jvm/jre/lib/amd64/libnet.so [0x2aaabd360269]
/.../jvm/jre/lib/amd64/libnet.so(Java_java_net_SocketOutputStream_socketWrite0+0xee) [0x2aaabd35cf4e]
[0x2aaaaeb3bf7f]
It seems like the JVM is deciding that the SIGPIPE that was raised from send should be passed along to our signal hander. Is it right when doing so?
Also, why is the call stack incomplete? I mean obviously it can't show me java code before socketWrite0 but why can't I see the stack before the java code?
The JVM can't tell whether the SIGPIPE came from it's own code, or your code. That information just isn't given by the signal. Because it doesn't want you to miss out on any possible events that you could be interested in, it has to pass you all SIGPIPEs, even the ones that it turns out were from its own code.
Unix signals come in two flavors -- "synchronous" and "asynchronous". A few exceptional conditions when just executing code can cause traps and result in "synchronous" signals. These are things such as unaligned memory access (SIGBUS), illegal memory access, often NULLs, (SIGSEGV), division by zero and other math errors (SIGFPE), undecodable instructions (SIGILL), and so forth. These have a precise execution context, and are delivered directly to the thread that caused them. The signal handler can look up the stack and see "hey I got an illegal memory access executing java code, and the pointer was a NULL. Let me go fix that up."
In contrast, the signals that interact with the outside world are the "asynchronous" variety, and include such things as SIGTERM, SIGQUIT, SIGUSR1, etc. These do not have a fixed execution context. For threaded programs they are delivered pretty much at random to any thread. Importantly, SIGPIPE is among these. Yes, in some sense, it is normally associated with one system call. But it is quite possible to (for instance) have two threads listening to two separate connections, both of which close before either thread is scheduled. The kernel just makes sure that there is a SIGPIPE pending (the usual implementation is as a bitmask of pending signals), and deals with it on rescheduling any of the threads in the process. This is only one of the simpler cases possible where the JVM might not have enough information to rule out your client code being interested in this signal.
(As to what happens to the read calls, they return "there was an error: EINTR" and continue on. At this point, the JVM can turn that into an exception, but the return happens after the signal delivery and the signal handler fires.)
The upshot is you'll just have to deal with false-positives. (And deal with getting only one signal where two might have been expected.)
Since there is no need to try/catch or specify un-checked exceptions, how are they are reported to the user?
how are they are reported to the user?
What is the best practice to handle
un-checked exceptions?
In our application, we barely use any exception at all: neither checked nor unchecked (we consider checked exceptions to be a Java idiosynchrasy unrelated to the problem domain we're dealing with, so we wrap most checked exceptions inside cleaner APIs, using state testing methods).
The way we deal with it is simple: it's a desktop application, if we catch an uncaught exception, we offer the user the possibility to send us a report. All the user has to do is click on "Report" and we get the full stack traces and other infos sent to one of our servers.
You can set up an application-wide uncaught exception handler like this:
Thread.setDefaultUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() {
public void uncaughtException( final Thread t, final Throwable e ) {
...
// Here we offer our user the possibility to 'report' the exception, YMMV
}
}
Typically there are zero exception happening in our software: we don't use checked exception for flow control (unless when we're using brain-dead APIs from the nineties, where this was common practice).
Some frameworks, like Spring, also have a pretty strong preference towards the "no checked exceptions" mentality.
So exceptions for us are really exceptionnal, hence the popup warning the user that the app crashed and offering them the possibility to send us the report.
If you are writing a container or a framework or a UI framework, then the best place to handle them is centrally, propagate them all the way to central handler and report the error to user in a usable way,
If using a UI, provide a way for user to report that exception.
Details:
We generally use a practice when using UI is that have a central exception handler.
In case of a web UI, we have on handler that shows the user that something has gone wrong in the system, The error page also has a form with hidden fields that has stack trace along with a description (optional) field asking the user to describe what she/he was doing when error occured. The for submits the error information, with stacktrace to the system (which can be a mail or simply stored in db)
In a desktop UI, could be the same, only thing that will be different is where you put your exception handling code.
Error reporting example
Error reporting example http://www.flickr.com/photos/aniketn/4785197367/
You actually can catch unchecked exceptions. It's just that they're usually things you can't solve when you do catch them - for example, NullPointerException. There's generally not a way to smoothly and gracefully resume whatever you were doing when the NullPointerException occurred.
If you don't handle them, they will propagate all the way up through your program and it will abort, dumping a stack trace of the exception.
The best practice is to deal with the ones where you can provide some better handling than the default. For example, if you call an external library function, you could wrap it in a try/catch block and if the library throws a NullPointerException you could give the user a friendly error message (a GUI "library X failed to do Y - did you specify a valid Z?") instead of a stack trace on the command line. But in the general case, the reason they're unchecked is because even if you knew about them, there'd be nothing for it but to throw up your hands.
When bubbling out of the main(...) method, the JVM prints the stack trace to System.out and exits that thread. For single-thread programs, that would also exit the program.
In general, every thread you run should have a wrapper catching Throwable so you can at least log it to your files.