关于环境:###

本文中的实战都是在docker容器中进行的,容器的出处请参照《在docker上编译openjdk8》一文,里面详细的说明了如何构造镜像和启动容器。

在上一篇文章《修改,编译,GDB调试openjdk8源码(docker环境下)》中,我们分析了虚拟机启动的代码,在阅读JLI_Launch函数的时候,发现调用了InitLauncher函数,如下图红框部分:

这个InitLauncher函数有何作用?展开后发现里面调用了JLI_SetTraceLauncher函数,而JLI_SetTraceLauncher函数的源码如下:

很简单,如果环境变量"_JAVA_LAUNCHER_DEBUG"的值不等于0,就将_launcher_debug的值设置为1。

_launcher_debug有什么用呢?我们看看/usr/local/openjdk/jdk/src/share/bin/jli_util.c文件中的JLI_TraceLauncher方法:

原来如此,只要_launcher_debug等于1,JLI_TraceLauncher方法在执行的时候就不会提前返回,而是把入参的信息做格式化再打印出来,在openjdk目录下全局搜索JLI_TraceLauncher函数,发现调用的地方还真不少呢,如下图,9个文件里都有调用:

在容器中执行vi /etc/profile命令,在内容的最底部新增两行脚本:

_JAVA_LAUNCHER_DEBUG=1
export _JAVA_LAUNCHER_DEBUG

如下图:

在执行以下命令使配置生效:

source /etc/profile

现在回到目录/usr/local/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin,执行./java -version,会发现输出的内容比以前丰富了很多,如下图,红框内是修改/etc/profile之前的输出,其他的全是新增的内容,这些新增的内容都是通过JLI_TraceLauncher输出的,以前由于没有环境变量_JAVA_LAUNCHER_DEBUG导致不输出,现在可以全部看到了:

虽然已通过设置环境变量_JAVA_LAUNCHER_DEBUG看到了更多的信息,但似乎意犹未尽,不如我们改一点openjdk源码,亲自调用一下JLI_TraceLauncher函数试试。

首先我们修改/usr/local/openjdk/jdk/src/share/bin/java.c,在JavaMain函数中,找到下面这一行:

在上面红框位置的下面增加一行代码JLI_TraceLauncher("static main method execute success (from boling_cavalry)");

这样代码的意思是在class类的main函数执行完毕后,输出一段文本信息"static main method execute success (from boling_cavalry)"

修改后如下图:

现在回到/usr/local/openjdk目录下,执行以下两个命令开始编译openjdk源码:

./configure --with-debug-level=slowdebug
make all ZIP_DEBUGINFO_FILES=0 DISABLE_HOTSPOT_OS_VERSION_CHECK=OK CONF=linux-x86_64-normal-server-slowdebug

jdk构建成功后,我们新建一个类Hello.java,在此位置新建:/usr/local/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin,这个类很简单:

public class Hello{
public static void main(String[] args){
System.out.println("hello world!");
}
}

在这个目录下执行./javac Hello.java生成Hello.class文件,再执行./java Hello,得到的输出如下:

红框中就是class中的输出以及我们修改openjdk源码添加的输出,达到我们的预期目的了,现在自定义的日志再加上上一章的GDB断点,可以帮助我们可以更好的阅读和实践openjdk源码,探索神秘的JVM。

欢迎关注我的公众号

最新文章

  1. 无限循环轮播图之JS部分(原生JS)
  2. USACO翻译:USACO 2012 JAN三题(1)
  3. MVC5 视图 不显示 Styles.Render Scripts.Render 问题解决
  4. JS存取Cookie值
  5. 关于SQL安装问题及安装前的准备
  6. 【转载】S2SH
  7. tomcat7禁用catalina.out输出
  8. strrchr函数
  9. WCF代理是怎么工作的?用代码说话
  10. Qt之图标切分与合并(关键是使用QPixmap的copy函数来拷贝整张图片的某个区域)
  11. 如何在settings里的休眠模式里添加永不休眠
  12. 文件描述符和exec() close_on_exec
  13. poj 1811 随机素数和大数分解(模板)
  14. poi excel 常用操作
  15. react异步加载组件
  16. 哈尔滨工程大学第十四届程序设计竞赛(同步赛)F 小帆帆走迷宫(dp)
  17. PostgreSQL 9.5.x的架构图及外存图
  18. jsp相关基础知识
  19. MySQL 命令总结
  20. shell 脚本实战笔记(8)--ssh免密码输入执行命令

热门文章

  1. [ PyQt入门教程 ] PyQt5基本控件使用:单选按钮、复选框、下拉框
  2. 数据结构-二叉搜索树和二叉树排序算法(python实现)
  3. Jmeter 接口测试参数处理
  4. Spark 系列(三)—— 弹性式数据集RDDs
  5. 在vue-cli 3中, 给stylus、sass样式传入共享的全局变量
  6. 一文速览Vue全栈
  7. AVL树(查找、插入、删除)——C语言
  8. C++7行代码实现求最大公约数
  9. ThreadLocalSingleton.h——base
  10. 终于,我感受到了IDEA的强大