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)
Here, it raises a SIGFPE.
You forgot to tell strace
to follow children. Add the -f
option to strace
and you should see something similar to:
[pid 2304] read(3, "\312\376\272\276\0\0\0001\0n\n\0\23\0I\t\0\3\0J\7\0K\n\0L\0M\n\0N\0"..., 2369) = 2369
[pid 2304] --- SIGFPE (Floating point exception) @ 0 (0) ---
[pid 2304] rt_sigreturn(0x1c50800) = 5
[pid 2304] write(2, "Exception in thread \"main\" ", 27Exception in thread "main" ) = 27
[pid 2304] write(2, "java.lang.ArithmeticException: /"..., 40java.lang.ArithmeticException: / by zero) = 40
[pid 2304] write(2, "\n", 1
Obviously this is because JVM has something like this in its code:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void fpe_handler(int signum) {
printf("JVM throws an ArithmeticException here...\n");
exit (1);
}
int main() {
int a = 5;
int b = 0;
signal(SIGFPE, fpe_handler);
printf("%d\n", a / b);
return 0;
}
Also JVM runs multiple threads (see clone()
in the log above or do ps -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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With