I wrote a very simple c program:
#include<stdio.h>
int main(){
int a=2;
int b=0;
printf("%d\n", a/b);
}
and run it with strace: strace ./a.out and get below output (only paste tail part)
... ...
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f04c7fb8000, 4096, PROT_READ) = 0
munmap(0x7f04c7f96000, 127640) = 0
--- SIGFPE (Floating point exception) @ 0 (0) ---
+++ killed by SIGFPE +++
Floating point exception
The output matches my expectation, as it was killed by SIGFPE signal.
However, the same program written in Java, doesn't get SIGFPE signal, does anybody know how java processes "divide by zero" exception?
public class Main {
public static void main(String[] args) {
int a = 2;
int b = 0;
System.out.println(a / b);
}
}
strace java -Xcomp Main
... ...
mprotect(0xf6949000, 8171520, PROT_READ|PROT_WRITE) = 0
mprotect(0xf6949000, 8171520, PROT_READ|PROT_EXEC) = 0
munmap(0xf774f000, 5727) = 0
mmap2(NULL, 331776, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xfffffffff68d0000
mprotect(0xf68d0000, 4096, PROT_NONE) = 0
clone(child_stack=0xf6920494, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xf6920bd8, tls=0xf6920bd8, child_tidptr=0xff9c5520) = 958
futex(0xf6920bd8, FUTEX_WAIT, 958, NULL) = 0
exit_group(0)
In contrast to (normal) C compile program, Java program runs on a runtime, and not on the processor, and is not platform dependent. Dividing by zero in java triggers ArithmeticException like this:
From JLS:
in java there is The term exception is shorthand for the phrase "exceptional event."
An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.
When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.
if u catch that exception then u can do what u wants to do after catching exception otherwise it is handle by default handler which show the error info and terminate the program ...
Dividing by zero in java make as ArithmeticException
Obviously this is because JVM has something like this in its code:
Also JVM runs multiple threads (see
clone()
in the log above or dops -eLf
when java is running) so that strace output is just incomplete.If a little more detail, unhandled SIGFPE indicates an error in the program, in which it occurred. And if java would be killed by SIGFPE, it would indicate than an error is in JVM, but not in your app, running inside JVM.
Java runs in a virtual machine (the JVM), which abstracts the hardware from the program. Most errors in a Java program will cause Java Exceptions and not trigger any native cpu or os error codes. I'd guess this code will throw an ArithmeticException (or something like that).
It might be that VM tests the divisor for 0 manually in emulated bytecode (for simplicity of implementation), but for performance will still switch to detecting the SIGFPE signal in JIT'd code. Try putting the division code in its own subroutine and call it in a loop thousands of times to ensure it gets compiled.
Here, it raises a SIGFPE.
You forgot to tell
strace
to follow children. Add the-f
option tostrace
and you should see something similar to: