From aa24b1aa08c25f2192fccbb4771e33ac5593cebe Mon Sep 17 00:00:00 2001 From: mmillson Date: Thu, 10 Oct 2024 06:45:52 -0400 Subject: [PATCH] Check if jvm options or system properties are being passed as command line options (and being ignored). --- .../krashpad/domain/jdk/FatalErrorLog.java | 71 +++++++++++++++++++ .../github/krashpad/util/jdk/Analysis.java | 10 +++ .../org/github/krashpad/analysis.properties | 2 + .../jdk/TestRegisterToMemoryMapping.java | 2 +- .../jdk/TestStackSlotToMemoryMapping.java | 2 +- .../krashpad/util/jdk/TestAnalysis.java | 24 +++++++ 6 files changed, 109 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/github/krashpad/domain/jdk/FatalErrorLog.java b/src/main/java/org/github/krashpad/domain/jdk/FatalErrorLog.java index c0711f1f..fe7acd38 100644 --- a/src/main/java/org/github/krashpad/domain/jdk/FatalErrorLog.java +++ b/src/main/java/org/github/krashpad/domain/jdk/FatalErrorLog.java @@ -1748,6 +1748,27 @@ && getOsVersion() == OsVersion.RHEL7 && getRhelVersion() != null && !getRhelVers if (isMultithreadedGc() && getActiveProcessorCount() > 0 && getActiveProcessorCount() < 2) { analysis.add(Analysis.ERROR_MULTITHREADED_COLLECTOR_LT_2_CPU); } + // Check for jvm options and system properties being passed as command line options + if (getJavaCommand() != null) { + String args = null; + // remove beginning and ending jar references + String regex = "^([^ ]+\\.jar)?(.+?(?=-jar))-jar .+$"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(getJavaCommand()); + if (matcher.find()) { + args = matcher.group(2); + } + if (args != null) { + JvmContext jvmContext = new JvmContext(args); + JvmOptions jvmOptions = new JvmOptions(jvmContext); + if (jvmOptions.getOptions().size() > 0) { + analysis.add(Analysis.ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS); + } + if (jvmOptions.getSystemProperties().size() > 0) { + analysis.add(Analysis.ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES); + } + } + } } /** @@ -1807,6 +1828,56 @@ public List getAnalysis() { a.add(new String[] { item.getKey(), event.getLogEntry() }); } } + } else if (item.getKey().equals(Analysis.ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS.toString())) { + StringBuffer s = new StringBuffer(item.getValue()); + JvmContext jvmContext = new JvmContext(getJavaCommand()); + JvmOptions jvmOptions = new JvmOptions(jvmContext); + Iterator>> iteratorOptions = jvmOptions.getOptions().entrySet() + .iterator(); + boolean punctuate = false; + while (iteratorOptions.hasNext()) { + Entry> option = iteratorOptions.next(); + if (!option.getKey().equals("undefined")) { + ArrayList opt = option.getValue(); + Iterator iteratorOption = opt.iterator(); + while (iteratorOption.hasNext()) { + if (punctuate) { + s.append(" "); + } + s.append(iteratorOption.next()); + punctuate = true; + } + } + } + s.append("."); + a.add(new String[] { item.getKey(), s.toString() }); + } else if (item.getKey().equals(Analysis.ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES.toString())) { + StringBuffer s = new StringBuffer(item.getValue()); + String args = null; + // remove beginning and ending jar references + String regex = "^([^ ]+\\.jar)?(.+?(?=-jar))-jar .+$"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(getJavaCommand()); + if (matcher.find()) { + args = matcher.group(2); + } + if (args != null) { + JvmContext jvmContext = new JvmContext(args); + JvmOptions jvmOptions = new JvmOptions(jvmContext); + ArrayList systemProperties = jvmOptions.getSystemProperties(); + Iterator iterator = systemProperties.iterator(); + boolean punctuate = false; + while (iterator.hasNext()) { + String systemProperty = iterator.next(); + if (punctuate) { + s.append(" "); + } + s.append(systemProperty); + punctuate = true; + } + s.append("."); + a.add(new String[] { item.getKey(), s.toString() }); + } } else if (item.getKey().equals(Analysis.ERROR_OOME_RLIMIT_MAX_MAP_COUNT.toString())) { StringBuffer s = new StringBuffer(item.getValue()); if (getGcPreciousLogWarning() != null) { diff --git a/src/main/java/org/github/krashpad/util/jdk/Analysis.java b/src/main/java/org/github/krashpad/util/jdk/Analysis.java index 1e941cb8..7c791caf 100644 --- a/src/main/java/org/github/krashpad/util/jdk/Analysis.java +++ b/src/main/java/org/github/krashpad/util/jdk/Analysis.java @@ -127,6 +127,16 @@ public enum Analysis { */ ERROR_ITEXT_IO("error.itext.io"), + /** + * Property key for JVM options being passed as command line options (and being ignored). + */ + ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS("error.java.command.has.jvm.options"), + + /** + * Property key for system properties being passed as command line options (and being ignored). + */ + ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES("error.java.command.has.system.properties"), + /** * Property key for an unknown JDK version. */ diff --git a/src/main/resources/org/github/krashpad/analysis.properties b/src/main/resources/org/github/krashpad/analysis.properties index c9048e71..c2c8e40c 100644 --- a/src/main/resources/org/github/krashpad/analysis.properties +++ b/src/main/resources/org/github/krashpad/analysis.properties @@ -18,6 +18,8 @@ error.gregoriancalendar.computetime=crash in java.util.GregorianCalendar.compute error.hashmap=Crash in java.util.HashMap. HashMap is not threadsafe. Check if the crash is due to multiple threads concurrently reading/writing to the HashMap. error.inspecting.top.of.stack= error.itext.io=Crash in StubRoutines from iText I/O due to a threading issue in the iText library where a file is attempting to be read before it is completely written to disk. Reference: https://access.redhat.com/solutions/5665601. +error.java.command.has.jvm.options=The following JVM options are being passed as command line arguments and being ignored: +error.java.command.has.system.properties=The following system properties are being passed as command line arguments and being ignored: error.jdk.version.unknown=Unknown JDK version. error.jdk.version.unsupported=Unsupported JDK version. krashpad targets JDK8+. Analysis may be incomplete (e.g. unidentified log lines). error.jdk8.deflater.contention=There is an application or operations invalid use case resulting in an attempt to modify a file while Java has it open. A workaround to avoid the crash is to disable memory mapping in ZipFile with -Dsun.zip.disableMemoryMapping=true (at the cost of some loss in performance), or upgrade to JDK 11. References: (1) https://access.redhat.com/solutions/2620091. (2) https://bugs.openjdk.org/browse/JDK-8145260. diff --git a/src/test/java/org/github/krashpad/domain/jdk/TestRegisterToMemoryMapping.java b/src/test/java/org/github/krashpad/domain/jdk/TestRegisterToMemoryMapping.java index c5a7cff7..6ec647fc 100644 --- a/src/test/java/org/github/krashpad/domain/jdk/TestRegisterToMemoryMapping.java +++ b/src/test/java/org/github/krashpad/domain/jdk/TestRegisterToMemoryMapping.java @@ -444,7 +444,7 @@ void testOops() { assertTrue(JdkUtil.identifyEventType(logLine, priorEvent) == JdkUtil.LogEventType.REGISTER_TO_MEMORY_MAPPING, JdkUtil.LogEventType.REGISTER_TO_MEMORY_MAPPING.toString() + " not identified."); } - + @Test void testParseLogLine() { RegisterToMemoryMapping priorLogEvent = new RegisterToMemoryMapping("Register to memory mapping:"); diff --git a/src/test/java/org/github/krashpad/domain/jdk/TestStackSlotToMemoryMapping.java b/src/test/java/org/github/krashpad/domain/jdk/TestStackSlotToMemoryMapping.java index 55e3af09..a8a2f5a9 100644 --- a/src/test/java/org/github/krashpad/domain/jdk/TestStackSlotToMemoryMapping.java +++ b/src/test/java/org/github/krashpad/domain/jdk/TestStackSlotToMemoryMapping.java @@ -475,7 +475,7 @@ void testDependencies() { JdkUtil.identifyEventType(logLine, priorLogEvent), JdkUtil.LogEventType.STACK_SLOT_TO_MEMORY_MAPPING.toString() + " not identified."); } - + @Test void testError() { StackSlotToMemoryMapping priorLogEvent = new StackSlotToMemoryMapping("Stack slot to memory mapping:"); diff --git a/src/test/java/org/github/krashpad/util/jdk/TestAnalysis.java b/src/test/java/org/github/krashpad/util/jdk/TestAnalysis.java index f7b4dc4f..e17e2570 100644 --- a/src/test/java/org/github/krashpad/util/jdk/TestAnalysis.java +++ b/src/test/java/org/github/krashpad/util/jdk/TestAnalysis.java @@ -1260,6 +1260,30 @@ void testItextIoStubRoutinesJintDisjointArrayCopyRandomAccessFileOrArray() { Analysis.ERROR_ITEXT_IO + " analysis not identified."); } + @Test + void testJavaCommandHasJvmArgss() { + FatalErrorLog fel = new FatalErrorLog(); + String jvm_args = "java_command: /deployments/quarkus-run.jar -XX:-UseParallelGC -XX:+UseSerialGC " + + "-Djava.util.logging.manager=org.jboss.logmanager.LogManager -jar /deployments/quarkus-run.jar"; + VmArguments event = new VmArguments(jvm_args); + fel.getVmArguments().add(event); + fel.doAnalysis(); + assertTrue(fel.hasAnalysis(Analysis.ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS.getKey()), + Analysis.ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS + " analysis not identified."); + assertEquals( + "The following JVM options are being passed as command line arguments and being ignored: " + + "-XX:-UseParallelGC -XX:+UseSerialGC.", + fel.getAnalysisLiteral(Analysis.ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS.getKey()), + Analysis.ERROR_JAVA_COMMAND_HAS_JVM_OPTIONS + " analysis literal not correct."); + assertTrue(fel.hasAnalysis(Analysis.ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES.getKey()), + Analysis.ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES + " analysis not identified."); + assertEquals( + "The following system properties are being passed as command line arguments and being ignored: " + + "-Djava.util.logging.manager=org.jboss.logmanager.LogManager.", + fel.getAnalysisLiteral(Analysis.ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES.getKey()), + Analysis.ERROR_JAVA_COMMAND_HAS_SYSTEM_PROPERTIES + " analysis literal not correct."); + } + @Test void testJavaSrSignum() { FatalErrorLog fel = new FatalErrorLog();