On Tue, 4 Feb 2025 01:10:34 GMT, Jiangli Zhou <jian...@openjdk.org> wrote:

> Please review runtime/jni/atExit/TestAtExit.java test change:
> 
> - Remove `BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libatExit := 
> java.base:libjvm`. Don't explicitly link with libjvm, because it adds 
> libjvm.so as a recorded dependency to libatExit.so (on Linux for example). 
> That requires libjvm.so must be resolved and loaded successfully when 
> libatExit.so is loaded. The static JDK (e.g. static-jdk image) does not 
> provide a libjvm.so for runtime usage.
> - Instead of calling the following functions directly in libatExit.c, change 
> to look up the functions and calls them using the retrieved function 
> addresses:
>   - JNI_GetDefaultJavaVMInitArgs
>   - JNI_GetCreatedJavaVMs
>   - JNI_CreateJavaVM
> 
> On Linux (and similar) platform, there is no need to call `dlopen` for libjvm 
> in libatExit.c explicitly, because the VM must already be loaded by the time 
> when the libatExit native code is executed. Using `RTLD_DEFAULT` can "find 
> symbols in the executable and its dependencies, as well as symbols in shared 
> objects that were dynamically loaded with the RTLD_GLOBAL flag" (see 
> https://man7.org/linux/man-pages/man3/dlsym.3.html).  
> https://github.com/openjdk/jdk/blob/9b49597244f898400222cfc252f50a2401ca3e2f/src/java.base/unix/native/libjli/java_md.c#L533
>  is where we `dlopen` libjvm with `RTLD_GLOBAL` for unix platform.
> 
> For Windows platform, I added Windows specific code to get the loaded 
> `jvm.dll` first. If it can't find loaded `jvm.dll`, it then get the handle of 
> the executable running the current process. The returned handle is used for 
> finding the function addresses. 
> 
> TestAtExit passes with 
> https://github.com/jianglizhou/jdk/actions/runs/13124407248/job/36619759000. 
> TestAtExit also pass on static-jdk with my local jtreg run.

I want to answer the question carefully to avoid possible confusions, so the 
comment below may provide extra information (also verbose) than just addressing 
the question. Please let me know if anything is unclear.

>   and as noted launchers have the choice of either linking with libjvm.so or 
> else using dynamic lookup. The former doesn't work with a static JDK (can we 
> link with libjvm.a?). 

Yes. A launcher executable can explicitly link with a native library, either 
using .so (shared library)  or .a (static library) if the launcher code has any 
direct references to symbols defined in the native library. The launcher can 
also choose to do dynamic symbol lookup and avoids the need for explicitly 
linking with the native library. 

If a launcher executable is linked with libjvm.so at build time, it requires 
libjvm.so to be resolved (normally from the RPATH) and loaded successfully when 
the launcher executable is loaded. Otherwise the executable fails to load and 
start due to the missing libjvm.so dependency. If a launcher executable is 
statically linked with libjvm.a, runtime does not try to find the libjvm.a 
since that is already built into the executable.

Same for a shared library (e.g. the libatExit.so used by the test) linked with 
libjvm.so, the shared library fails to be loaded if libjvm.so do not present at 
runtime.  

If launcher code choose to use dynamic symbol lookup and avoids linking with 
libjvm.so, the launcher code can support both dynamic case and static case. The 
`java` launcher does that.

> So in the context of fixing a couple of tests this is okay.

Yeah, since there are just few cases in the tests, I feel fixing these tests 
seem to be a good choice.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/23431#issuecomment-2635599602

Reply via email to