java进程的dump,java进程coredump(一)

点击量:1180

上篇文章介绍了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代码,调用本地方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

publicclassCoreDumpTest{

//native关键字修饰的方法是对本地方法的声明,具体实现由本地方法完成

publicnativevoidcrash();

static{

//静态方法,载入本地动态库。load方法载入的是绝对路径下面的库

//也可以使用loadLibrary,调用的是"java.library.path"下面的库

//这个方法需要把生成的动态库加到目录里面,比较麻烦,我这边就直接使用绝对路径了。

System.load("/home/fanyy/crash.so");

}

publicstaticvoidmain(String[]args){

newCoreDumpTest().crash();

}

}

2.编译,生成.class文件

1

javacCoreDumpTest.java

3.生成头文件:CoreDumpTest.h

1

javahCoreDumpTest

该文件的内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class CoreDumpTest */

#ifndef_Included_CoreDumpTest

#define_Included_CoreDumpTest

#ifdef__cplusplus

extern"C"{

#endif

/*

* Class:     CoreDumpTest

* Method:    crash

* Signature: ()V

*/

JNIEXPORTvoidJNICALLJava_CoreDumpTest_crash

(JNIEnv*,jobject);

#ifdef__cplusplus

}

#endif

#endif

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

4.编写具体的本地代码

实现头文件中的方法,命名为crash.c

1

2

3

4

5

6

7

8

#include"jni.h"

#include"CoreDumpTest.h"

JNIEXPORTvoidJNICALLJava_CoreDumpTest_crash

(JNIEnv*env,jobjectobj){

int*p=NULL;

*p=3;

}

5.生成动态库

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

1).生成目标文件:

1

gcc-I/usr/local/jdk/include-I/usr/local/jdk/include/linux-fPICcrash.c

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

2).生成so文件

1

gcc-shared-fPIC-ocrash.socrash.o

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

当然了,这两步也可以合并成一步:

1

gcc-shared-fPIC-ocrash.so-I/usr/local/jdk/include-I/usr/local/jdk/include/linuxcrash.c

6.运行

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

[fanyy@VM_72_32_tlinux~/fanyy]$javaCoreDumpTest

#

#AfatalerrorhasbeendetectedbytheJavaRuntimeEnvironment:

#

#SIGSEGV(0xb)atpc=0x00007f37956cd554,pid=23687,tid=139881182439168

#

#JREversion:6.0_22-b04

#JavaVM:JavaHotSpot(TM)64-BitServerVM(17.1-b03mixedmodelinux-amd64)

#Problematicframe:

#C[crash.so+0x554]Java_CoreDumpTest_crash+0x18

#

#Anerrorreportfilewithmoreinformationissavedas:

#/home/astd/fanyy/javacoredump/hs_err_pid23687.log

#

#Ifyouwouldliketosubmitabugreport,pleasevisit:

#http://java.sun.com/webapps/bugreport/crash.jsp

#ThecrashhappenedoutsidetheJavaVirtualMachineinnativecode.

#Seeproblematicframeforwheretoreportthebug.

#

Aborted(coredumped)

Duang!coredump了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值