Chapter 3. Debug symbols for Red Hat build of OpenJDK 17
Debug symbols help in investigating a crash in Red Hat build of OpenJDK applications.
3.1. Installing the debug symbols
This procedure describes how to install the debug symbols for Red Hat build of OpenJDK.
Prerequisites
Installed the
gdb
package on your local sytem.-
You can issue the
sudo yum install gdb
command on your CLI to install this package on your local system.
-
You can issue the
Procedure
To install the debug symbols, enter the following command:
$ sudo debuginfo-install java-17-openjdk $ sudo debuginfo-install java-17-openjdk-headless
These commands install
java-17-openjdk-debuginfo
,java-17-openjdk-headless-debuginfo
, and additional packages that provide debug symbols for Red Hat build of OpenJDK 17 binaries. These packages are not self-sufficient and do not contain executable binaries.NoteThe
debuginfo-install
is provided by theyum-utils
package.To verify that the debug symbols are installed, enter the following command:
$ gdb
which java
Reading symbols from /usr/bin/java...Reading symbols from /usr/lib/debug/usr/lib/jvm/java-17-openjdk-17.0.2.0.8-4.el8_5/bin/java-17.0.2.0.8-4.el8_5.x86_64.debug...done. (gdb)
3.2. Checking the installation location of debug symbols
This procedure explains how to find the location of debug symbols.
If the debuginfo
package is installed, but you cannot get the installation location of the package, then check if the correct package and java versions are installed. After confirming the versions, check the location of debug symbols again.
Prerequisites
Installed the
gdb
package on your local sytem.-
You can issue the
sudo yum install gdb
command on your CLI to install this package on your local system. - Installed the debug symbols package. See Installing the debug symbols.
-
You can issue the
Procedure
To find the location of debug symbols, use
gdb
withwhich java
commands:$ gdb which java Reading symbols from /usr/bin/java...Reading symbols from /usr/lib/debug/usr/lib/jvm/java-17-openjdk-17.0.2.0.8-4.el8_5/bin/java-17.0.2.0.8-4.el8_5.x86_64.debug...done. (gdb)
Use the following commands to explore the
*-debug
directory to see all the debug versions of the libraries, which includejava
,javac
, andjavah
:$ cd /usr/lib/debug/lib/jvm/java-17-openjdk-17.0.2.0.8-4.el8_5
$ tree OJDK 17 version: └── java-17-openjdk-17.0.2.0.8-4.el8_5 ├── bin │ ... │ │── java-java-17.0.2.0.8-4.el8_5.x86_64.debug │ ├── javac-java-17.0.2.0.8-4.el8_5.x86_64.debug │ ├── javadoc-java-17.0.2.0.8-4.el8_5.x86_64.debug │ ... └── lib ├── jexec-java-17.0.2.0.8-4.el8_5.x86_64.debug ├── jli │ └── libjli.so-java-17.0.2.0.8-4.el8_5.x86_64.debug ├── jspawnhelper-java-17.0.2.0.8-4.el8_5.x86_64.debug │ ...
The javac
and javah
tools are provided by the java-17-openjdk-devel
package. You can install the package using the command: $ sudo debuginfo-install java-17-openjdk-devel
.
3.3. Checking the configuration of debug symbols
You can check and set configurations for debug symbols.
Enter the following command to get a list of the installed packages:
$ sudo yum list installed | grep 'java-17-openjdk-debuginfo'
If some debug information packages have not been installed, enter the following command to install the missing packages:
$ sudo yum debuginfo-install glibc-2.28-151.el8.x86_64 libgcc-8.4.1-1.el8.x86_64 libstdc++-8.4.1-1.el8.x86_64 sssd-client-2.4.0-9.el8.x86_64 zlib-1.2.11-17.el8.x86_64
Run the following command if you want to hit a specific breakpoint:
$ gdb -ex 'handle SIGSEGV noprint nostop pass' -ex 'set breakpoint pending on' -ex 'break JavaCalls::call' -ex 'run' --args java ./HelloWorld
The above command completes the following tasks:
- Handles the SIGSEGV error as the JVM uses SEGV for stack overflow check.
-
Sets pending breakpoints to
yes
. -
Calls the break statement in
JavaCalls::call
function. The function to starts the application in HotSpot (libjvm.so).
3.4. Configuring the debug symbols in a fatal error log file
When a Java application is down due to a JVM crash, a fatal error log file is generated, for example: hs_error
, java_error
. These error log files are generated in current working directory of the application. The crash file contains information from the stack.
Procedure
You can remove all the debug symbols by using the
strip -g
command.The following code shows an example of non-stripped
hs_error
file:Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0xb83d2a] Unsafe_SetLong+0xda j sun.misc.Unsafe.putLong(Ljava/lang/Object;JJ)V+0 j Crash.main([Ljava/lang/String;)V+8 v ~StubRoutines::call_stub V [libjvm.so+0x6c0e65] JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0xc85 V [libjvm.so+0x73cc0d] jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*) [clone .constprop.1]+0x31d V [libjvm.so+0x73fd16] jni_CallStaticVoidMethod+0x186 C [libjli.so+0x48a2] JavaMain+0x472 C [libpthread.so.0+0x9432] start_thread+0xe2
The following code shows an example of stripped
hs_error
file:Stack: [0x00007ff7e1a44000,0x00007ff7e1b44000], sp=0x00007ff7e1b42850, free space=1018k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0xa7ecab] j sun.misc.Unsafe.putAddress(JJ)V+0 j Crash.crash()V+5 j Crash.main([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub V [libjvm.so+0x67133a] V [libjvm.so+0x682bca] V [libjvm.so+0x6968b6] C [libjli.so+0x3989] C [libpthread.so.0+0x7dd5] start_thread+0xc5
Enter the following command to check that you have the same version of debug symbols and the fatal error log file:
$ java -version
NoteYou can also use the
sudo update-alternatives --config 'java'
to complete this check.Use the
nm
command to ensure thatlibjvm.so
has ELF data and text symbols:$ nm /usr/lib/debug/usr/lib/jvm/java-17-openjdk-17.0.2.0.8-4.el8_5/lib/server/libjvm.so-17.0.2.0.8-4.el8_5.x86_64.debug
Additional resources
-
The crash file
hs_error
is incomplete without the debug symbols installed. For more information, see Java application down due to JVM crash.