在学习《JAVA虚拟机精讲》的过程中,根据书中的实战案例,自己动手修改了Launcher的源码,即java.c,现做一记录。
在launcher的源码中添加一些自定义的模块,满足特定的业务场景。
第一步:修改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
至此,调试完毕。