修改hotspot源码,使用GDB调试

在学习《JAVA虚拟机精讲》的过程中,根据书中的实战案例,自己动手修改了Launcher的源码,即java.c,现做一记录。

在launcher的源码中添加一些自定义的模块,满足特定的业务场景。

第一步:修改java.c

  • 文件位置:/hotspot/src/share/tools/launcher/java.c;
  • 在java.c中定义自己的函数:

/*添加自定义函数*/

void getParameters(jstring mainClassName,JNIEnv *env,jclass mainClass,jmethodID mainID,jobjectArray mainArgs){

    printf("成功接收到变量参数...");

}

  • 调用函数

/*在调用CallStaticVoidMethod()函数之前,引用其变量参数*/

    getParameters(mainClassName, env, mainClass, mainID, mainArgs);

    /* Invoke main method. */

    (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

第二步:编译hotspot

在/hotspot/make目录下执行make jvmg命令,编译后文件存放于/hotspot/build/linux/linux_amd64_compiler2/jvmg目录下,初次编译比较耗时,后面若只修改java.c文件,因为采用增量编译,可很快完成编译。

第三步:修改env.sh和jdkpath.sh

. ./env.sh

./gamma -version

执行此命令,可以启动虚拟机,输出版本号。

在hotspot调试脚本中,通过jdkpath.sh获取运行时jdk环境,此处修改为和openJDK编译后的版本。

如果编译版本和运行版本不一致,运行时会报错,JVM允许向下兼容。

第四步:调试

命令:./hotspot -gdb -classpath /application/ Hello

修改hotspot调试脚本,添加断点,进行debug。

# Get us to a point where we can set breakpoints in libjvm.so

break InitializeJVM

run

break getParameters

run

# Stop in InitializeJVM

delete 1

执行至第一个breakpoint,执行continue命令,放过,至第二个breakpoint,执行info args命令,输出参数信息。

(gdb) info args

mainClassName = 0x7ffff000cde0

env = 0x7ffff000b210

mainClass = 0x7ffff000cde8

mainID = 0x7ffff0074af8

mainArgs = 0x7ffff000ce08

至此,调试完毕。



你可能感兴趣的:(JDK&JVM)