From 2b6b4fd779a1bd7b78ab0126cfaaa0a7c5b77ed1 Mon Sep 17 00:00:00 2001 From: Steve Loughran Date: Thu, 29 Sep 2016 11:35:00 +0100 Subject: [PATCH] HADOOP-13663 Index out of range in SysInfoWindows. Contributed by Inigo Goiri --- .../apache/hadoop/util/SysInfoWindows.java | 58 ++++++++++--------- .../hadoop/util/TestSysInfoWindows.java | 7 ++- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/SysInfoWindows.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/SysInfoWindows.java index 490c1277dae..e21adac1b20 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/SysInfoWindows.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/SysInfoWindows.java @@ -100,36 +100,40 @@ public class SysInfoWindows extends SysInfo { String sysInfoStr = getSystemInfoInfoFromShell(); if (sysInfoStr != null) { final int sysInfoSplitCount = 11; - String[] sysInfo = sysInfoStr.substring(0, sysInfoStr.indexOf("\r\n")) - .split(","); - if (sysInfo.length == sysInfoSplitCount) { - try { - vmemSize = Long.parseLong(sysInfo[0]); - memSize = Long.parseLong(sysInfo[1]); - vmemAvailable = Long.parseLong(sysInfo[2]); - memAvailable = Long.parseLong(sysInfo[3]); - numProcessors = Integer.parseInt(sysInfo[4]); - cpuFrequencyKhz = Long.parseLong(sysInfo[5]); - cumulativeCpuTimeMs = Long.parseLong(sysInfo[6]); - storageBytesRead = Long.parseLong(sysInfo[7]); - storageBytesWritten = Long.parseLong(sysInfo[8]); - netBytesRead = Long.parseLong(sysInfo[9]); - netBytesWritten = Long.parseLong(sysInfo[10]); - if (lastCumCpuTimeMs != -1) { - /** - * This number will be the aggregated usage across all cores in - * [0.0, 100.0]. For example, it will be 400.0 if there are 8 - * cores and each of them is running at 50% utilization. - */ - cpuUsage = (cumulativeCpuTimeMs - lastCumCpuTimeMs) - * 100F / refreshInterval; + int index = sysInfoStr.indexOf("\r\n"); + if (index >= 0) { + String[] sysInfo = sysInfoStr.substring(0, index).split(","); + if (sysInfo.length == sysInfoSplitCount) { + try { + vmemSize = Long.parseLong(sysInfo[0]); + memSize = Long.parseLong(sysInfo[1]); + vmemAvailable = Long.parseLong(sysInfo[2]); + memAvailable = Long.parseLong(sysInfo[3]); + numProcessors = Integer.parseInt(sysInfo[4]); + cpuFrequencyKhz = Long.parseLong(sysInfo[5]); + cumulativeCpuTimeMs = Long.parseLong(sysInfo[6]); + storageBytesRead = Long.parseLong(sysInfo[7]); + storageBytesWritten = Long.parseLong(sysInfo[8]); + netBytesRead = Long.parseLong(sysInfo[9]); + netBytesWritten = Long.parseLong(sysInfo[10]); + if (lastCumCpuTimeMs != -1) { + /** + * This number will be the aggregated usage across all cores in + * [0.0, 100.0]. For example, it will be 400.0 if there are 8 + * cores and each of them is running at 50% utilization. + */ + cpuUsage = (cumulativeCpuTimeMs - lastCumCpuTimeMs) + * 100F / refreshInterval; + } + } catch (NumberFormatException nfe) { + LOG.warn("Error parsing sysInfo", nfe); } - } catch (NumberFormatException nfe) { - LOG.warn("Error parsing sysInfo", nfe); + } else { + LOG.warn("Expected split length of sysInfo to be " + + sysInfoSplitCount + ". Got " + sysInfo.length); } } else { - LOG.warn("Expected split length of sysInfo to be " - + sysInfoSplitCount + ". Got " + sysInfo.length); + LOG.warn("Wrong output from sysInfo: " + sysInfoStr); } } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestSysInfoWindows.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestSysInfoWindows.java index 555157678c3..fc99aeb976f 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestSysInfoWindows.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestSysInfoWindows.java @@ -141,10 +141,15 @@ public class TestSysInfoWindows { @Test(timeout = 10000) public void errorInGetSystemInfo() { SysInfoWindowsMock tester = new SysInfoWindowsMock(); - // info str derived from windows shell command has \r\n termination + // info str derived from windows shell command is null tester.setSysinfoString(null); // call a method to refresh values tester.getAvailablePhysicalMemorySize(); + + // info str derived from windows shell command with no \r\n termination + tester.setSysinfoString(""); + // call a method to refresh values + tester.getAvailablePhysicalMemorySize(); } }