直接执行 javah JavaMain.java 生成JavaMain.h头文件 /* DO NOT EDIT THIS FILE - it is machine generated */ #include...接下来就是编译,为了方便,我们使用make工具来执行编译过程。这里需要编写Makefile。对Makefile不熟的兄弟可以参考Makefile文件编写。...我的jdk就安装在/usr/local/java/jdk1.8.0_144下 接下来就是编译,直接执行make命令,成功生成libcpp.so文件。...执行 javac JavaMain.java 得到JavaMain.class 执行: java -Djava.library.path='.'...2.png 有以下几点需要注意: 执行javah和java命令要在源码目录下,也就是src/java目录下。 执行java命令来运行时候,需要制定java.library.path的路径。
main()函数最终会阻塞当前线程,同时用另外一个线程去调用JavaMain()函数。...return rslt; } Linux 系统下(后面所说的Linux系统都是指基于Linux内核的操作系统)创建一个 pthread_t 线程,然后使用这个新创建的线程执行JavaMain()函数。...方法的第一个参数int (JNICALL continuation)(void )接收的就是JavaMain()函数的指针。...下面就来看一下JavaMain()函数的实现,如下: 位置:/openjdk/jdk/src/share/bin/java.c int JNICALL JavaMain(void * _args){...当成功与主线程断开连接后,当前线程一直等待程序中所有的非守护线程全部执行结束,然后调用本地函数jni_DestroyJavaVM()对JVM执行销毁。
OpenJDK版本 ➜ jdk hg id 76072a077ee1+ jdk-11+28 当我们运行Java命令后,Java程序本身的main方法会首先被执行 C文件src/java.base/share...ret : rslt; } } 该方法最终会调用ContinueInNewThread0方法,开启一个系统线程,且该线程的入口函数是JavaMain。...看下JavaMain方法 C文件src/java.base/share/native/libjli/java.c int JNICALL JavaMain(void * _args) { ......该方法就是我们的最终方法,它会先调用InitializeJVM初始化JVM,再通过一系列的方法获取mainClass、mainArgs,最终调用(*env)->CallStaticVoidMethod 方法真正的执行我们提供的...有关(*env)->CallStaticVoidMethod究竟是如何执行的Java main方法,以及Java main方法又是如何调用的其他Java方法,我们之后会另起文章详细分析。
也在此传给子线程,子线程创建成功后,会先执行JavaMain(也就是continuation参数) if (pthread_create(&tid, &attr, (void *(*)(void...,然后这个注释出现了,告诉我“如果因为某些原因(例如内存溢出)导致创建线程失败,当前线程还会继续执行JavaMain,但是在后续的操作中依然有可能发生错误,例如JNI_CreateJavaVM函数会创建一些新的线程...,因此,在当前线程执行JavaMain只是做一次尝试”。...至次,本次阅读,修改,调试和编译openjdk8的实践就结束了,其实JavaMain函数做了很多事情,这次只是看到其中打印信息的那一部分而已,后面的加载class,执行java类等都还没有看到,有兴趣的读者可以先对...java的类加载做个初步了解,再继续阅读JavaMain函数,相信您会有更多收获的。
先来回顾一下那篇文章,对于C/C++程序而言,从创建进程到进入main函数,主要就是经历了四个阶段: 进程 & 主线程创建阶段 主线程启动执行并进行进程级初始化操作(如加载系统动态链接库) 主线程进入可执行文件的入口...咱们就从这个可执行文件入手,以Linux系统上的Java8版本为例,用反汇编神器IDA打开可以看到,这个可执行文件的入口: image.png 和咱们在上一篇分析的流程符合,进入这个程序启动入口后,...来看传给它的第一个参数,这是新线程启动后将要执行的入口函数:JavaMain。...JavaMain 这个函数的名字就有点意思了,看起来,快要进入Java的地界儿了,加油继续看下去: int JNICALL JavaMain(void * _args) { // ......// ... // 调用它 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); // ... } JavaMain
pthread_join(tid, &tmp); rslt = (int)(intptr_t)tmp; } else { rslt = JavaMain...ThreadJavaMain 直接调用了 JavaMain,所以这里的逻辑就是,如果创建线程成功,就由新线程执行 JavaMain,否则就知道在当前进程执行JavaMain。...JavaMain 是我们关注的重点,核心逻辑如下: int JavaMain(void* _args) { JavaMainArgs *args = (JavaMainArgs *)_args;...其次,fork 返回了两次,clone 也是一样,但它们都是返回到系统调用后开始执行,pthread_create 如何让新线程执行 start_routine 的?...截止到此处,所有的代码都是当前进程执行的,新线程并没有执行。 从第 7 步开始的代码,当前进程和新线程都会执行。对当前进程而言,程序将它第 3 步入栈的寄存器出栈。
LoadJavaVM 去加载libjvm 调用方法ParseArguments 去解析参数 最后调用JVMInit 去启动JVM JVMInit 这个方法就跟操作系统有关了,如下图所示不同的系统会去执行不同的文件的中代码...ContinueInNewThread方法,并在方法ContinueInNewThread 中调用不同操作系统的ContinueInNewThread0方法,如下图所示: 这样我们就来到了第一天,用Clion调试JDK源码时的JavaMain...方法 JavaMain 方法 这里还是以打印版本号为例,可以看到在444行,有如下代码: if (printVersion || showVersion) { PrintJavaVersion(...CallStaticVoidMethod(env, ver, print, printTo); } 我们在Idea中,引入11的JDK , 然后就可以看到对应的输出 总结 至此,java -version的执行过程
Java程序main方法执行流程 当我们编写完java源代码程序后,经过javac编译后,执行java命令执行这个程序时,是怎么一步步的调用到我们程序中的main方法的呢?...java命令是在安装jre/jdk时配置到系统环境路径中去的,执行java命令时会找到bin目录下的java可执行程序,并将我们编译后的java程序类名传递进去就可以执行了。...这个结构体InvocationFunctions会一直当做参数传递到JavaMain函数中。...之后再JavaMain函数中,会根据JNI_CreateJavaVM虚拟机创建函数来初始化虚拟机,此时已经是在一个新的线程中运行了。...创建VMThread,并开始执行。
这篇文章的链接在这里:https://mp.weixin.qq.com/s/lYajWCb-ov8ctSkvdAmIUw 所以执行 main 函数以后,main 线程就退出了,新旧 APM 都一样。...(String[] args) { System.out.println("in main"); } } 接下来我们来调试源码看看,JVM 运行以后会进入 java.c 的 JavaMain...方法, int JNICALL JavaMain(void * _args) { // ... /* Initialize the virtual machine */ InitializeJVM...CallStaticVoidMethod(env, mainClass, mainID, mainArgs); // main 方法结束以后接下来调用下面的代码 LEAVE(); } JavaMain
从IDE的输出结果右侧上的红色方块说明JVM进程并没有退出,另外 mac上执行ps -eaf | grep java会输出结果,也可以证明这个结论。...image.png 如上在启动线程前设置线程为守护线程,从输出结果可知JVM进程已经终止了,执行ps -eaf |grep java 也看不到JVM进程了。...中在main线程运行结束后,JVM会自动启动一个叫做DestroyJavaVM线程,该线程会等待所有用户线程结束后终止JVM进程,下面通过简单的JVM代码来证明这个结论: 翻开JVM的代码,最终会调用到JavaMain...这个c函数 int JNICALL JavaMain(void * _args) { ......//执行Java中的main函数 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); //main
main函数返回了JLI_Launch()函数,位于 src/java.base/share/native/libjli/java.c 2 java.c # JLI_Launch() JavaMain...在该方法里会执行虚拟机的初始化,获取Java程序主类及main方法,然后通过JNI调用main方法, 自此,整个JVM进程执行结束,最终退出。...int JavaMain(void *_args) { JavaMainArgs *args = (JavaMainArgs *) _args; int argc = args->argc...会执行一系列关于虚拟机的分配、挂载、初始化等工作, 且听下回分解
第二步:执行 configure 命令。...make 不过友情提示:命令执行后,可以冲杯咖啡,边品咖啡边等待,估计要一杯咖啡的功夫。 ?...进入编译成功的 jdk 目录,执行如下命令,查看 JDK 的版本。 ./java -version 输出如下,大功告成,喜大普奔。 ?...万事俱备就差设置断点调试啦,找到虚拟机启动的执行入口 java.c,然后在 JavaMain 方法上设置断点,开始运行调试,效果如下。 ?...还是针对执行入口 java.c 的 JavaMain 方法操作,加入一行代码(人过留名,雁过留声),改动如下。 ?
Java main方法 jvm启动流程分析 配置JVM装载环境 Java代码执行时需要一个JVM环境,JVM环境的创建包括两部分:JVM.dll文件的查找和装载。...执行main方法 ?...线程栈大小确定后,通过ContinueInNewThread方法创建新线程,并执行JavaMain函数,JavaMain函数的大概流程如下: 1、新建JVM实例 InitializeJVM方法调用InvocationFunctions...4、执行main方法 ?...最终通过JavaCalls::call执行main方法,到此Jvm调用main方法启动类的完整流程就讲完了。
使用遗漏函数 ---- rce RCE英文全称:remote command/code execute 分为远程命令执行ping和远程代码执行evel。 漏洞出现的原因:没有在输入口做输入处理。...危险等级:高 shell_exec() 功能描述:通过 Shell 执行命令,并将执行结果作为字符串返回。...> 三.利用环境变量LD_PRELOAD来绕过php disable_function执行系统命令 php的mail函数在执行过程中会默认调用系统程序/usr/sbin/sendmail,如果我们能劫持...具体实现如下 1.编制我们自己的动态链接程序,代码如下(功能是执行mkdir test) 执行编译为一个动态共享库的命令如下 gcc -c -fPIC a.c -o a gcc -shared a -o...使用windows 系统组件com (1)phpinfo 中 com.allow_dcom 开启 什么是com 组件: COM组件是以WIN32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行代码组成
因为launcher是一个类级别属性,所以这个操作会被收敛到类构造器()方法,在该类被加载的初始化阶段被执行。 ...GetCreatedJavaVMs; } InvocationFunctions; 关于jvmpath,需要再回到JLI_Launch函数中,在该函数中会调用CreateExecutionEnvironment函数创建执行上下文...准备工作做完之后,进入JVMInit函数执行JVM初始化流程,同样进入win的实现,在java_md.c中: int JVMInit(InvocationFunctions* ifn, jlong threadStackSize...,所以最终执行的是JavaMain函数 arg4:传递给线程的参数指针 arg5:线程初始状态 arg6:记录threadId地址 关于STACK_SIZE_PARAM_IS_A_RESERVATION...我们只需要关心线程调用的函数:JavaMain。
/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test 进入GDB后,输入如下命令: break java.c:JavaMain continue...第一条命令表示在源文件java.c的JavaMain函数入口处设置断点;第二条命令表示让中断的程序继续运行,直到运行完程序后退出GDB,并在终端打印”Hello World!...查看当前栈帧局部变量的值 list(l) 列出源代码,接着上次的位置往下列,每次列10行ll list(l) 行号 列出从指定行开始的源代码 list(l) 函数名 列出指定的函数的源代码 next(n) 执行下一行语句...print(p) 打印表达式的值,通过表达式可以修改变量的值或者调用函数 quit(q) 退出gdb调试环境 step(s) 执行下一行语句,如果有函数调用则进入到函数中 start 开始执行程序,停在
Python 是如何执行的?执行顺序是怎么样? 至上而下,逐行执行 #!...什么是 Python 脚本的执行入口 类比:进入一栋大楼肯定有个大门入口,赛车要进入赛道也一定有一个入口 所以,执行程序,也需要一个入口 一般称代码执行的入口叫做主函数(main 函数) 执行入口(主函数...假设运行的是 xiaoming.py,那么就会执行主函数 假设运行的是 xiaohong.py,即使 xiaohong 导入了 xiaoming,也不会执行 xiaoming.py 里面的主函数(main...函数) 是否一定需要执行入口(主函数) 不一定 假设没有主函数,那么运行 xiaoming.py 时,就会至上而下,逐行运行 xiaoming.py 的所有代码 执行入口的意义 将业务代码写在主函数上面...,主函数用来调用有业务代码,代码结构整洁 向 Java、C、Golang 看齐,他们都是要求一个程序必须有一个主执行入口才能正确运行
前言 ABAP程序有2种执行方法 一个前台执行 另一个是后台运行。 后者,所谓后台执行就是在某一个时间段,程序自动运行,俗称位 JOB。...本次将讲解讨论:1.前台执行和后台执行的区别, 2.后台执行的方式,和后台debug的方法。 ---- 一、前台执行和后台执行的不同之处? 前台:通过画面来操作,称之位前台执行。...后台:不通过画面操作的处理,称之位后台执行。 总结:就是执行方式不一样,执行的内容都是一样的。(一个能看到画面,一个看不到画面)。...二、后台执行 后台执行因为不会设计到画面,所以会节省很多资源,但是在执行的之后需要给执行的程序事先事先设置好参数(variant) 1.后台执行的优势 与前台执行相比优势有2点。...1.1 规划性,后台执行可以选择 任意的时间段去执行,就行闹铃一样,只要你设定好了之后就可以定时执行。
顺序执行命令,条件执行 有时候等一条指令执行,时间太久,不妨堆起来一起执行,执行完一条再下一条 每条指令用;隔开就可以啦 sudo apt-get update; sudo apt-get install...some-toll; some-toll && 选择执行 前边的命令返回值为0则执行后边的 $?...命令可以查看上次的返回值 || 表示 前边的不为0 则执行 管道 管道是什么,管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式就是将前面每一个进程的输出
以上这篇python 串行执行和并行执行实例就是小编分享给大家的全部内容了,希望能给大家一个参考。
领取专属 10元无门槛券
手把手带您无忧上云