java进程coredump(一)

点击量:754

上篇文章介绍了coredump的基本知识以及gdb调试core文件的相关操作,这篇文章主要介绍如何生成Java进程的coredump,也就是说如何写一段java代码使它被操作系统kill掉。我们都知道因为jvm的存在,java层面的代码无论你怎么写都是不太可能crash的,顶多是OOM或者stackoverflow,然而这些都会被jvm捕捉并抛出异常,而不是被操作系统直接kill掉。所以如果一个java进程crash掉,那肯定是挂在native code上了(当然JVM本身的bug就另说了),因此思路就是通过java的JNI(java native interface)调用本地方法,使进程挂掉。具体步骤如下:

1.编写java代码,调用本地方法

2.编译,生成.class文件

3.生成头文件:CoreDumpTest.h

该文件的内容如下:

这段代码是自动生成的,不可以修改,我们可以看到有一个声明的函数叫:Java_CoreDumpTest_crash,接下来我们需要用C来具体实现这个函数。

4.编写具体的本地代码
实现头文件中的方法,命名为crash.c

5.生成动态库
生成动态库的过程分为两步:先生成目标文件,再生成so文件。
1).生成目标文件:

参数-I表示需要引入的头文件的目录,-fPIC表示编译的是位置无关代码(position independent code),也就是说这段编译的代码使用的都是相对地址,而不是绝对地址,所以加载器在把代码加载到内存的时候可以放到任意位置,而不需要根据当前的内存地址重新定位。
2).生成so文件

值得注意的是,如果你遇到这个报错:relocation R_X86_64_32 against `.rodata’ can not be used when making a shared object; recompile with -fPIC,很有可能是上一步上成目标文件时没有加上参数-fPIC,因为动态库的编译是基于目标文件的,如果要编译位置无关的动态库,他所需要的目标文件也必须是位置无关的。
当然了,这两步也可以合并成一步:


6.运行

Duang!coredump了!

参考:
百度百科-Java JNI
gcc编译静态和动态库

发表评论

电子邮件地址不会被公开。 必填项已用*标注